[net.lang.c] Jumping into blocks

kwh@bentley.UUCP (KW Heuer) (04/23/86)

In article <275@copper.UUCP> copper!stevesu (Steve Summit) writes:
>Most people agree that goto's are pretty acceptable for handling
>error conditions.  For instance:
>
>	if(stbuf.st_uid != getuid()) {
>nope:		printf("I don't think you want to delete this file.\n");
>		return;
>	}
>	if(strcmp(name, "vmunix") == 0) goto nope;
>	unlink(name);
>	return;

As has been pointed out, this particular example can be handled easily with
the || operator.  But here's a real example I keep running into:

	while (argc > 1 && argv[1][0] == '-') {
	    switch (argv[1][1]) {
	    ...
	    default:
usage:		fputs("usage: a.out [flags] args\n", stderr);
		exit(1);
	    }
	    --argc;  ++argv;
	}
	if (!aflag && !bflag && !cflag) goto usage;

A trivial variation is to have "goto usage" after "default:" and put the
actual usage message inside the "if" -- this makes it a forward goto, but
still into a block.

So, assuming that goatooze are acceptable for error handling, but jumping
into a block is forbidden, what's the best way to write this?  Use two
braches, and hide the common code at the bottom of main()?  Set an error
flag and test it outside the while?  (Ugh, that requires an artificial
boolean *and* a break statement.)  Make usage() a non-returning function
instead of a label?  (My usual preference.)  Duplicate the code?

Karl W. Z. Heuer (ihnp4!bentley!kwh), The Walking Lint

chris@toram (04/26/86)

In article <737@bentley.UUCP> kwh@bentley.UUCP (KW Heuer) writes:
>In article <275@copper.UUCP> copper!stevesu (Steve Summit) writes:
>>Most people agree that goto's are pretty acceptable for handling
>>error conditions.  For instance:
>>
>>	[example deleted]
>
> ... But here's a real example I keep running into:
>
>	[example deleted]
>
>So, assuming that goatooze are acceptable for error handling, but jumping
>into a block is forbidden, what's the best way to write this?  Use two
>braches, and hide the common code at the bottom of main()?  Set an error
>flag and test it outside the while?  (Ugh, that requires an artificial
>boolean *and* a break statement.)  Make usage() a non-returning function
>instead of a label?  (My usual preference.)  Duplicate the code?

What's wrong with a flag and and "break"s?  "Break" after an error condition
is perfectly obvious, especially when the error test is right after the
loop.  Or duplicate the code, when it's so trivial.  What's a couple of
lines in the interest of readability?  Sure "goto"s can sometimes make
complicated things more readable (e.g., saving putting great chunks
of code in several nests of "if"s), but why on earth use it to make a
nice, straightforward error test obscure?

ARPA@brl-smoke (04/29/86)

>>So, assuming that goatooze are acceptable for error handling, but jumping
>>into a block is forbidden, what's the best way to write this?  Use two
>>braches, and hide the common code at the bottom of main()?  Set an error
>>flag and test it outside the while?  (Ugh, that requires an artificial
>>boolean *and* a break statement.)  Make usage() a non-returning function
>>instead of a label?  (My usual preference.)  Duplicate the code?

I've seen two variations that *I* prefer:

	1) If you're in a condition that calls for bailing out, use a function
	   that prints an error message (to the appropriate place) and call
	   exit(). This is what I tend to use for usage/fatal error kinds of
	   situations.

	2) In some (kernel) routines, one may have several "error" conditions
	   that have a common set of "cleanup procedures" (like setting an
	   error code or some such thing) before returning. In this case,
	   several "gohtoose" that wind up at the bottom of the routine seem
	   the neatest (well, least sloppy) way of doing it.

I've used the other variations that you mentioned, but wouldn't in anything
that anyone else would have to see/support.

	Rich Brown
	Downers Grove, IL

P.S.	I take that back. I've never jumped into a block like that. I think
	I would put that under the heading of "tacky".

franka@mmintl (04/29/86)

In article <737@bentley.UUCP> kwh@bentley.UUCP writes:
>So, assuming that goatooze are acceptable for error handling, but jumping
>into a block is forbidden, what's the best way to write this?  Use two
>branches, and hide the common code at the bottom of main()?

Yes.  Exception handlers belong at the bottom of the routine.  It isn't
"hidden" there -- that's the first place I would look for it.  I would
describe it as being hidden in your code (for whichever case it is being
jumped to).

Duplicating the code is also acceptable.  It depends mostly on a comparison
of two considerations: (1) how likely are there to be more instances where
the code is to be used in later versions of the routine, and (2) how likely
is it that later versions will want a different error message for the two
cases?

Frank Adams                           ihnp4!philabs!pwa-b!mmintl!franka
Multimate International    52 Oakland Ave North    E. Hartford, CT 06108