Tuesday, December 1, 2009

Objective-C Tuesdays: goto

Last time we looked at using the continue statement to skip to the next iteration of a loop. This week, we will finish looking at loops with the most primitive looping statement of all: the goto statement.

A goto statement always references a label, which is simply an identifier followed by a colon (:). When the goto statement is reached, execution jumps to the label and continues from that point. The label can be before or after the goto statement.
// goto and label examples

start: // label named "start"
  // do some stuff
  if (...) {
    goto start;
  }
  // do more stuff
  if (...) {
    goto end;
  }
  // and more stuff
end: // label named "end"
Labels do nothing by themselves except mark places in code that you can jump to using goto.

The goto statement has one big limitation: it only works within a single function. If you write something like this:
// goto may only jump to labels within a function
// THIS CODE DOESN'T COMPILE

void function1(void) {
  label1:
  goto label2;
}

void function2(void) {
  label2:
  goto label1;
}
The compiler will produce error messages like label ‘label1’ used but not defined. Without this restriction, goto could be abused to create difficult to understand spaghetti code (ask any old time BASIC programmer about this). Because of this restriction, label names are local to the function that contains them, so you can use the same label name in different functions.

Though mostly eschewed in favor of the for, for...in, while and do...while loops, the goto can be used to implement loops:
int i = 0;
startLoop: // label "startLoop"
  NSLog(@"%d", i);
  i++;
  if (i < 10) {
    goto startLoop;
  }
This loop logs the numbers from 0 to 9. It's equivalent to this while loop:
int i = 0;
while (i < 10) {
  NSLog(@"%d", i);
  i++;
}
Because the other looping statements are more compact and expressive, you will rarely see goto used to build loops. Next time, we'll look at common uses for goto.

6 comments:

Eimantas said...
This comment has been removed by a blog administrator.
joel said...

do not use goto for anything ever!
http://xkcd.com/292/

Patrick Alessi said...

Why? Why dear God, why are you revealing this to novice programmers?

Don McCaughey said...

@Patrick goto is part of the language, for good or bad. Sooner or later every Objective-C programmer is going to run across some code that uses it. I think it's important for novice programmers to understand how goto works and where it might be used.

@joel I've never used a goto statement in 20+ years of programming in C/C++/Objective-C (and never been attacked by dinosaurs :-) but I have occasionally seen it used in places. Some programmers would argue that there are legitimate uses for goto, which I'll discuss next week.

I think most programmers quickly figure out that goto usually makes your code convoluted and brittle and shy away from it. Those who don't typically make a mess of their code whether they use goto or not.

Evan Robinson said...

Goto Considered Harmful

Don McCaughey said...

@Evan "Goto Considered Harmful" is a classic essay, but it was written 40 years ago. At the time, many programs were still written in assembly code, or in languages like BASIC and FORTRAN that had an unrestricted GOTO statement but lacked facilities like user defined functions or procedures for adding structure. Using jmp or GOTO was often the only practical way to control the flow of your program.

Languages like Pascal and C were created around this time and have very strong structured programming features but very limited goto statements. When you read "Goto Considered Harmful", you need to keep in mind that Dijkstra is not addressing this kind of limited goto.