[net.lang.c] "break <label>" vs. "goto <label>"

tracy@hcrvx1.UUCP (Tracy Tims) (01/11/85)

>> Yuck!  "break <n>;" is an accident looking for a place to happen!
>> If one has to have this facility, "break <label>;" is far superior.

> And "goto <label>" is even better, you don't have to change the language
> at all.

In "break <label>;" the label is used to identify the control structure being
exited, rather than the place being exited to.  It is more robust in terms of
future program changes, and it has the advantage of being defined only in terms
of structured constructs.

	loop1:	while ( <cond1> ) {
			.
			.
		while ( <cond2> ) {
			.
			break loop1;
			.
		}
			.
			.
	}

                              Tracy Tims    {linus,allegra,decvax}!watmath!...
   Human Computing Resources Corporation                     {ihnp4,utzoo}!...
 Toronto, Ontario, Canada.  416 922-1937                   ...hcr!hcrvx1!tracy

guy@rlgvax.UUCP (Guy Harris) (01/12/85)

> By this reasoning we can quickly reduce ourselves to working with a turing
> machine. A while statement is redundant because we have goto and if 
> statements. "break <label>" reflects a structured concept that mirrors how I
> view a problem being solved; besides it is not as random and clumsy as a goto.

The difference is that writing a "while" loop using "if" and "goto" yields
clumsy and harder-to-read code; replacing the word "break" with the word
"goto" merely makes the program "goto"-less.  A "break" (or a "continue") is
a fairly arbitrary transfer of control; "goto" is, admittedly, more arbitrary,
but all of them require you to read a bit to discover where control is
actually going.

	for (<something) {
		while (<something else>) {
			.
			.
			.
			break foobar;
		}
	}
foobar:

is no less clumsy than

	for (<something) {
		while (<something else>) {
			.
			.
			.
			goto foobar;
		}
	}
foobar:

The only possible merit of labelled "break" and "continue" is that they
can't be misused in the ways that "goto" can.  There are many ways of
writing poor code, and since we can't make "goto" go away in C we're stuck
with that particular way.  We'll have to rely on education to prevent
spaghetti code.  (There are instances where using "goto"s to cause two
separate paths through code to join at common code is *more* readable, say,
than duplicating the code.  Admittedly, in the one recent instance I've
written of this sort, the whole thing should be done using a different
technique of joining those paths, but that's competing with several other
items on my TODO list.)

	Guy Harris
	{seismo,ihnp4,allegra}!rlgvax!guy

tim@callan.UUCP (Tim Smith) (01/12/85)

Turnh on :-) mode.

In the two methods for breaking loops:

	/*						/*
	 * Method A					 * Method B
	 */						 */
	loop:	while ( foo )				while ( foo )
		{					{
			.					.
			.					.
			break loop;				goto endloop;
			.					.
		}					}
						endloop:;

many people seem to prefer A, because the label is at the start of the
loop, rather than at the end of the loop.

It seems to me that the obvious thing to do is to change the goto statement.
Goto should have the form

		goto	label [ {+,-} constant_expression ] ;

The constant expression tells how many statements away from the label
to 'goto'.  For example, the while loop break would be written like this:

	/*
	 * Method C
	 */
	loop: while ( foo )
	      {
		      .
		      .
		      goto loop + 1;
		      .
	      }

Exit :-) mode

How are 'do' loops to fit in with 'break label'?
Does the 'label' go with the 'do' or the 'while'?
-- 
Duty Now for the Future
					Tim Smith
			ihnp4!wlbr!callan!tim or ihnp4!cithep!tim

rpw3@redwood.UUCP (Rob Warnock) (01/19/85)

+---------------
| How are 'do' loops to fit in with 'break label'?
| Does the 'label' go with the 'do' or the 'while'?
| 	Tim Smith | 	ihnp4!wlbr!callan!tim or ihnp4!cithep!tim
+---------------

The label goes with the "do", since it is a "do" statement. "Break <label>"
says: "Go to just outside the labelled statement". (See K & R for "statement".)

Keep in mind, that any "break <label>" should also (for orthogonality) work
on a "compound statement", not just on loops. The semantics are the same. The
normal "continue" construct can be thought of as a "break <label>" for which
the labelled statement is the loop BODY, not the loop itself.

	while (...){			while (...)  zork:{
		...				...
		if (...) continue;		if (...) break zork;
		...				...
	}				}

The application to multi-level loops is straightforward.

p.s. If we're going to change the language, I vote for the generic
"leave <label>" of any labelled statement (a. la. BLISS), rather than
twisting the meanings of the current "break" and "continue".


Rob Warnock
Systems Architecture Consultant

UUCP:	{ihnp4,ucbvax!dual}!fortune!redwood!rpw3
DDD:	(415)572-2607
USPS:	510 Trinidad Lane, Foster City, CA  94404