break, continue, return, goto

BALDWIN mike at whuxl.UUCP
Sat Nov 2 13:22:26 AEST 1985


This is in response to those who think that break, continue, and
multiple returns are bad things.  As with anything, they can be
abused, but I find continue and multiple returns extremely useful
for dealing with errors, and break for ending complicated search loops.
In fact, that covers 99% of the ways I use them.  Here are some typical
examples:

	/* using continue for error handling in loops */
	for (i = 1; i < argc; i++) {
		if ((fp = fopen(argv[i], "r")) == NULL) {
			perror(argv[i]);
			continue;
		}
		if (some other reason this arg is bad) {
			process(error);
			continue;
		}
		/* code to deal with a good arg */
		while ((c = getc(fp)) != EOF)
			munch(c);
	}

	/* using break for ending a complicated search loop */
	for (m = meeble; m < meeble + NMEEBLE; m++)
		if (m->glop == forp && m->zip == fweep) {
			printf("zeegle %2s", m->yorg);
			m->blazzo += IGUAP;
			break;
		}

/*
 * Using multiple returns for error cases.
 */
int
monge(file, index)
char	*name;
int	index;
{
	if (index < 0 || index >= MAXIDX) {
		puts("yikes!");
		return ERR;
	}
	if (stat(file, &st) < 0) {
		perror(file);
		return ERR;
	}
	if (some other reason I can't deal with this) {
		process(error);
		return error code;
	}
	/* code to deal with a good call */
	chmod(file, tab[index].mode);
	unlink(file);
	calculate(newindex);
	return newindex;
}

----
These are clear and obvious uses for break et al., and they reflect
how I *think* about the problems!!  E.g., in the first for loop, I
think:  "Ok, I have a file to process.  Obviously, if I can't open
it, or something weird is wrong with it, then skip it.  Once all the
trivial tests for validity are out of the way, go ahead and process it."
Now with the next for loop, the test could be built into the for stmt,
but that would be quite unreadable.  I read it thusly:  "Go through
the meeble array.  When you find a glop and zip match, do something
magic, then get out."

Now how would you code these things *sanely* without using break,
continue, and multiple returns?  Is the code you end up with the
way you actually *think* about the problem?  (Don't tell me you
think in boolean flags!)

A high level picture of how I view a block of code:

	block_of_code(x)	/* x is an arg or a loop var */
	{
		/* error checks */
		check_validity(x);
		check_for_space();
		check_anything_else();

		/* main body of code */
		process(x);
		munch(x);
		murgolate(x);
	}

Where the checks end with continue or return.  Also note that my style stops
things from marching off the right side of the page because of trivial error
tests.  The main code that works on x is only one indentation level in.

Anyway, the gist of this is:  I find break, continue, and return very
useful and map well into how I think (which, I'll admit, can border on
paranoid schizophrenia sometimes :-) :-| :-( :-@ ), and I would be utterly
lost in time, and lost in space, without them ("help me, Mommy!").

"Madness takes its toll."			Michael Baldwin "Bruce"
						{at&t}!whuxl!mike



More information about the Comp.lang.c mailing list