Breaking out of several nested loops (& ANSI C)

Charlie Martin crm at duke.UUCP
Sat Oct 13 03:58:16 AEST 1984


The problem with getting into a religious discussion is that
everyone seems to think that you have a religious opinion...

Let me make another attempt to make my argument clear -- I claim that
while it is indeed true that ANY algorithm can be expressed in
proper structured-programming-without-goto's (proven by Boehm &
Jacopini), there are things which one often wants to do which are
best expressed in current programming languages (modulo efficiency
constraints) by doing them with a goto.  The example that we have
been discussing is one of those.

The solutions that are available are: use a branching statement to
bust out of the loop; have a language construct which magically
hides a branching contruct busting out of the loop; or put a new
boolean test into each outer loop, so that processing terminates
when that is set.

The third solution is the one that can be inferred from the original
proof.  It has some advantages for proof-of-correctness.

The second method is the one that is used by the break (and continue)
statements, and is the one that I feel is correct.  It limits the scope
of the goto, and doesn't tempt people into indiscetions as often.
However, these statements as they exist won't cover certain cases:
for example, a simple break won't take you out of nested loops; a
more difficult example is something like this:
	
	/* code for user input */
	while ( not complete )
	do
	   retry:
	   /* transfer to this point for retry of whole thing */

		while( not right)
		do
		   get input a, b, c
		   if ABORT-INPUT received
			goto retry 
		   fi
		od

	od 
	/* end example */.

In both of these cases, WHILE IT IS PROVABLY POSSIBLE TO WRITE A
GOTO-LESS PROGRAM TO DO THEM, the solution with goto's has advantages
in speed and amount of generated code-and-data.

The best solution is something that eliminates goto's or limits their
ability to muck up control flow, but that provides for all those odd
situations which these exemplify.  A label-continue/label-break sentax
might do that effectively (say by defining the label as an optional part
of the beginning and/or ending of a loop) but I want to feel convinced
that it is going to be able to do everything I would use a goto for
(which isn't damnall much, I admit -- I've only written one goto in C
ever.)  (And wouldn't have ever written one in Pascal at all, were it
not for the absense of a loop break.)

My only complaints about the labelled-loop/break-label solution are
these:
	1) it's a goto anyway -- why fuss about it?  In particular,
	   why claim it is more ``structured'' than the same control-
	   flow with the horrible word ``goto'' in the code?

	2) The notation suggested is itself counter-intuitive --
	   you are G*T*-ing to a label, but the label is up at
	   the top and you are going to the bottom (!?)

	3) do these solutions *really* cover everything?  Are you
	   going to leave setjmp/longjmp in the language?  They
	   can be transformed out too, you know...

Charlie Martin
(...mcnc!duke!crm)



More information about the Comp.lang.c mailing list