Re^3: gotos

Richard A. O'Keefe ok at quintus.UUCP
Sat Apr 30 19:03:45 AEST 1988


In a fine series of postings, kenny at uiucdcsb.cs.uiuc.edu showed us how
the gotos in Knuth's "Structured ... Gotos" could be avoided in a "modern"
language by using
    (1)	gotos	(alias 'break', 'continue', 'return')
    (2) adding state variables (the very special case of ungetc())
    (3) duplicating code

Dijkstra's original argument against 'goto's was that when you look at a
labelled statement you may have no idea what it means for the program to
have reached that point.  While 'break' and 'continue' are tamer than
general gotos, in that they can only be used to exit control structures,
not to enter them improperly, I suggest that they can be much _worse_
for program maintenance than the gotos Knuth was advocating.

What gives me such a crazy idea?  The fact that they are anonymous.
If I want to see where a break or continue takes me, I may have to scrabble
around matching braces.  The big advantage of a goto in C is that the label
has a name.  _If_ you adopt the practice of always flushing labels left,
_if_ you use gotos with _care_, and _if_ you put a comment after each label
saying what it means to be at that point, it can be a lot easier for
someone to figure out what is going on.  I will take a goto over "break 2"
any day (fortunately C hasn't got "break 2", but it has been suggested
several times in this newsgroup).

The ideal, of course, is something which combines the clarity of a label
with the tameness of a 'break', to wit a named exit.  (Escape functions
are even nicer, but they're not C's style.)  While C hasn't got a named
exit, we can get the same effect with macros:

	#define BEGIN(id) {
	#define END(id) ; id:; }
	#define LEAVE(id) goto id
/*example*/
	BEGIN(search)
	    for (i = n; --i >= 0; )
		if (a[i] == sought) {
		    /* "found" processing */
		    LEAVE(search);
		}
	    /* "not found" processing */
	END(search)

A fairly straightforward awk script can be used to check that BEGIN and
END match up and that LEAVE is properly in scope.  [Left as an exercise
for the reader (:-).]



More information about the Comp.lang.c mailing list