18.3.3: goto

[This section corresponds to K&R Sec. 3.8]

Finally, C has a goto statement, and labels to go to. You will hear many people disparage goto statements, and without taking a stand on whether they are inherently evil, I will say that most code can be written, and written pretty cleanly, without them.

You can attach a label to any statement:

	label1:	statement2;
	label2:	statement4;
A label is simply an identifier followed by a colon. The names for labels follow the same rules as for variables and other identifiers (they consist of letters, digit characters, and underscores, generally beginning with a letter, in any case not beginning with a digit). A label can in principle have the same name as a variable; variables and labels are quite distinct, so the compiler can keep them separate. Label names must obviously be unique within a function.

Anywhere you want, you can say

	goto label ;
where label is one of the labels in the current function, and control flow will jump to that point. You can only jump around within the same function; you can't go to a label in some other function. (If goto isn't enough for you, if for some reason you must jump back to another function, there's a library function, longjmp, which will do so under certain circumstances.) If you jump into a brace-enclosed block of statements, and if that block has local, automatic variables which have initializers (that is, attached to their declarations), the initializers will not take effect. (In other words, initializers for block-local variables take effect only when the block is entered normally, from the top.)

For the vast majority of functions, the more ``structured'' if/else, switch, and loop statements, perhaps augmented with break and continue statements, will accomplish the required control flow, in a clean and obvious way. (Without practice, it may not always be immediately obvious how to structure a piece of code as, say, a clean loop, but the more important point is that once it's structured as a clean loop, it will be more obvious to a later reader what it's doing.) Remember, too, that function calls and return statements also accomplish control flow (analogous to the GOSUB in BASIC) in a clean and structured way. The complaint about goto is that when it's used without restraint, a tangled mess of unwieldy ``spaghetti code'' often results. There are really only two times you ever need to use a goto statement in real programs:

  1. To break out of several loops at once. (When you have nested loops, the break statement only breaks you out of the innermost loop it's in.)
  2. To jump to the end of a function, to perform some cleanup code or something, but bypassing the rest of the function. Usually, such a jump-to-the-end happens as a result of some error condition which the function has detected.

It's customary for an author to claim that, although goto exists, ``it has not been used in this book'', or that the author can count on the fingers of one hand the number of times he's ever used goto in C, and in fact I think I can make these claims myself.

Read sequentially: prev next up top

This page by Steve Summit // Copyright 1996-1999 // mail feedback