Breaking out of several nested loops

Chris Miller chris at hwcs.UUCP
Wed Oct 24 21:25:48 AEST 1984


In all the discussion on the merits and/or degree of structuredness of
constructs such as "break <unsigned integer>" or "break <label>" I have
not yet seen anyone observe that C ALREADY has a partial mechanism for
getting out of several nested loops without using a GOTO - it is
called "return"!

Example (using current C - translate ad lib. to your favourite syntax,
	and make identifiers unique within 6 chars :-)):

	level_1:
		while (condition_1)
		{
			while (condition_2)
			{
				while (condition_3)
				{
					switch (condition_4)
					{
					case AGAIN:
						goto Cont;
						/* I.E. continue level_1 */
					case FINISHED:
						goto Done;
						/* I.E. break level_1 */
					default:
						...
					}
				}
			}
	Cont:
		}
	Done:
Becomes:

	level_1(/* Parameters from current environment */);
	...
level_1(/* Parameters */)
{
	while (condition_1)
		if (level_2(/* Parameters */) == Done)
			return;
}
level_2(/* Parameters */)
{
	while (condition_2)
	{
		while (condition_3)
		{
			switch(condition_4)
			{
			case AGAIN:
				return Cont;
			case FINISHED:
				return Done;
			default:
				...
			}
		}
	}
	return Done;
}

If you want multi-level breaks/continues, it is even possible to return
a count indicating how many levels of loop are to be exited.

Let me defend myself instantly from rising hackles and cries of
"Efficiency!".  If you really have a collection of nested loops, then
in most cases, the cost of starting up the outer ones is small compared
with the cost of repeatedly executing the innermost one.  It may
therefore not be altogether unreasonable to parcel the whole lot up as
a separate function; it is likely in most cases to be a great deal more
readable that way, as well.

Lest anyone still be inclined to flame, a few more points:

1.  I am NOT saying that the above is "more" or "less" structured than
    any other proposal.  Simply wrapping things in procedures does not
    automatically render them structured, modular, maintainable,
    readable, or anything else!
2.  I AM pointing out that if you want to write unstructured code in C,
    you don't even need the existing "goto", "break", or "continue"
    statements - "return" is quite sufficient (let alone "longjmp",
    "exit", or, if you want to be truly obscene, "kill" to transfer
    control to a routine which has been set up for signal trapping :-)).
3.  I am NOT seriously advocating the above translation as a general
    technique - often a solution with "goto" is perfectly appropriate
    and comprehensible.
4.  I do not believe that "goto" should be banned from C (on the principle
    of not breaking existing software), and on the whole do not favour
    introducing unnecessary further constructs - if there had never been
    a "goto" in C to start with, things would be different, but there was
    so they aren't.
5.  The REAL problem with any construct, structured or otherwise is that it
    becomes hard to read if applied to too large a physical scope (very large
    loop bodies, distant targets of "break", etc.).  On C compilers which
    support multi-line macro definitions (i.e. V7 and most later ones) a
    considerable gain in clarity, at no cost in efficiency, can be gained
    by packaging loop bodies as macros, even if they only appear once in
    the code.
6.  I am a computational atheist.
-- 
			Chris Miller
			Department of Computer Science
			Heriot-Watt University
			...!ukc!{edcaad,west44}!hwcs



More information about the Comp.lang.c mailing list