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