Breaking out of several nested loops (& ANSI C)

Tony L. Hansen hansen at pegasus.UUCP
Sun Oct 14 01:10:24 AEST 1984


This following is a formal proposal for an addition to the ANSI Standard C
language. This is a modification of an August draft of the standards document.

						Tony Hansen
						pegasus!hansen
----
Subject: labels

Currently labels are allowed within the language only as targets of goto
statements. I would like to propose that they be allowed in two additional
places as well: as arguments to the break and continue statements.

Consider the code fragment

	while (...) {
	    weekloop:
		while (...) {
			...
			switch (...) {
				...
				case ...:
					...
					goto endloop;
				...
					goto endloop2;
				...
			}
		...
		endloop: ;
		}
		endloop2:
		...
	}

Where does the "goto endloop" logically take us?  What it is actually doing
is continuing the second while loop (labeled weekloop).  Is it obvious from
the code?  I think that when looking at that code and seeing the goto, I
would look for the label, possibly scanning the entire function for it.
Finally I would find the label within the same loop as the switch statement.
I would then see the closing brace following the label and search back for
the matching opening brace. Finally I would see that it is a pair of braces
from a while loop and going to that place will do the same thing as a
continue of that loop.

Similarly, where does the "goto endloop2" logically take us? What it is
actually doing is breaking out of the second while loop. Is that obvious
from the code? I feel that the same mental juggling around would have to be
done to figure out what the real affect of the goto is.

Instead, I would like to propose the following code fragment:

	while (...) {
		weekloop:
		    while (...) {
			...
			switch (...) {
				...
				case ...:
					...
					continue weekloop;
				...
					break weekloop;
				...
			}
		...
		}
		...
	}

Here I have used the logically extended continue and break statements to
accept a label argument. Think through the mental juggling that now has to
be done to realize what happens when the continue statement is reached:
"Hmmm, weekloop has to have been defined above. ... There it is. And it's
being continued. That's simple enough to follow." Similarly for the new
break statement. I can tell almost at a glance which loop is being continued
or broken out of rather than doing all sorts of mental juggling to figure 
out what the goto is really doing.

I propose that section 6.5 be rewritten along the following lines:

    6.5 Jump statements

    The jump statements (goto, continue, break, and return) cause an
    unconditional jump to another place.

    6.5.1 Labeled statements

    Syntax
	    identifier : statement

    Constraints

	Any statement may be preceded by a label prefix that serves to declare
    the identifier as a label. The only use of a label is as a target of a
    goto, continue or break statement. The labels are in a separate name space
    from other identifiers.

    6.5.2 goto statements

    Syntax
	    goto identifier ;

    Semantics
	Control may jump unconditionally by means of the goto statement. The
    identifier must be a label located anywhere in the current function.

    6.5.3

    Syntax
	    continue identifier   ;
			       opt

    Constraints
	A continue statement may appear only in a loop body. The optional
    identifier must be a label prefixing a while, for or do iteration
    statement enclosing the continue statement.

    Semantics
	A continue statement causes a jump to the loop-continuation portion of
    the enclosing iteration statement; that is, to the end of the loop. If no
    label is specified, the smallest enclosing iteration statement is used;
    otherwise the labeled enclosing iteration statement is used. More
    precisely, in each of the statements

      loop:		      loop:		      loop:
	while (...) {		do {			for (...) {
	  ...			  ...		 	 ...
	  continue;		  continue;	  	continue;
	  ...			  ...		  	...
	  continue loop;	  continue loop;  	continue loop;
	  ...			  ...		  	...
	contin: ;		contin: ;		contin: ;
	}			} while (...);		}

    unless the continue shown without a label reference is in an enclosed
    iteration statement (in which case it is interpreted within that
    statement), it is equivalent to "goto contin;". (Following the contin: is
    a null statement.) Irregardless of other enclosing iteration statements,
    the "continue loop" statement is equivalent to "goto contin;".

    6.5.4 The break statement

    Syntax
	    break identifier   ;
			    opt

    Constraints
	A break statement may appear only in a switch body or loop body. The
    optional identifier must be a label prefixing a switch statement, or a
    while, for or do iteration statement, enclosing the break statement.

    Semantics
	A break statement without a label identifier terminates execution of
    the smallest enclosing switch or iteration statement. A break statement
    with a label identifier terminates execution of the enclosing switch or
    iteration statement which is prefixed with the named identifier. More
    precisely, in each of the statements

      loop:		      loop:		      loop:
	while (...) {		do {			for (...) {
	  ...			  ...		 	 ...
	  break;		  break;	  	break;
	  ...			  ...		  	...
	  break loop;	  	break loop;  		break loop;
	  ...			  ...		  	...
	}			} while (...);		}
      contin:		      contin:		      contin:
	...			...			...

    unless the break shown without a label reference is in an enclosed switch
    or iteration statement (in which case it is interpreted within that
    statement), it is equivalent to "goto contin;". Irregardless of other
    enclosing switch or iteration statements, the "break loop" statement is
    equivalent to "goto contin;".

    6.5.5 The return statement
    ....



More information about the Comp.lang.c mailing list