I've been programming in C++ for a couples months now, and when I go through forums I've noticed a trend. It seems that goto
statements are generally regarded as being either completely wrong to use, or should only be used in very specific circumstances. What is it about goto
statements that makes them so fundamentally wrong?

- 60,462
- 10
- 96
- 117

- 85
- 1
- 1
- 10
-
3You may want to start from [here](http://en.wikipedia.org/wiki/Considered_harmful) – Andy Prowl Apr 28 '13 at 18:28
-
*goto* statements are not "fundamentally wrong" - optimized assembly code is full of jumps that serve the same purpose. But *goto* make code hardly readable by humans - what is good for a machine is often not so good for a human being. – SChepurin Apr 28 '13 at 18:48
-
Goto has been out of favor since the 1960s. However some famous authors, like Knuth, still use them. – brian beuning Apr 28 '13 at 19:03
2 Answers
The biggest reason is that it makes the code hard to follow. The goto
isn't implicitly bad; it's just easy to write hard-to-follow code with it.
For example, which would you rather read? This:
int factorial(int n) {
int result;
if(n==0 || n==1)
result = 1;
else
result = n*factorial(n-1);
return result;
}
Or this:
int factorial(int n) {
int result;
if(n > 1)
goto big;
result = 1;
goto end;
big:
result = n*factorial(n-1);
end:
return result;
}
The two implementations are the same to a machine, but the first is much clearer to our human eyes. There are times when goto
is clearer, though. For example, consider this from C (or C++ without exceptions):
void process_big_file(FILE* foo) {
if(possible_failure_1(foo))
goto cleanup;
// Do some work
if(possible_failure_2(foo))
goto cleanup;
// Do some more work
cleanup:
fclose(foo);
}
Here, using goto
makes sense because it lets you put all the cleanup code in one place, and the goto
s actually create a logical flow of execution. In particular, when reading the code, it's obvious that you always (a) reach cleanup code, and (b) always reach the same cleanup code, which is the important thing here. In the absence of exceptions, I'd actually argue that goto
is The Right Thing when trying to organize (for example) cleanup code.

- 6,957
- 5
- 28
- 48
-
2That last example should never be used in C++. Even without exceptions, you always have RAII which works with error codes/early returns too. – Pubby Apr 28 '13 at 18:42
-
As a rule I agree, but sometimes RAII just doesn't fit. In such cases you need a good old pointer (not even an `auto_ptr`, which would implement RAII for you), and then you have to do cleanup manually. A good example is an object graph with circular references, since RAII-type objects and `auto_ptr` both use either (a) object lifecycle or (b) reference counting (respectively) to do cleanup. And, of course, sometimes you to plug into legacy C code, and then all hell breaks loose. :) – sigpwned Apr 28 '13 at 18:48
-
@sigpwned The last example is a perfect example of poorly designed code, in which a function is doing too much. – James Kanze Apr 28 '13 at 19:00
-
I have written interface code that crosses the C/C++ boundary, and you sometimes have to use `goto` to clean things up, even though the code is technically C++ (for example, we had code that would switch which heap was used, and the cleanup for that didn't happen in a destructor). – Mats Petersson Apr 28 '13 at 19:02
The main reason is that goto
makes reasoning about the code extremely difficult, if not impossible. (Note that the same thing holds for "hidden" goto's, like using a break
to exit from the middle of a loop.) In general, if you want to be able to reason about the correctness of code, you want to enter each block at the top, and leave it at the bottom. And without being able to reason about the correctness of code, you can't be sure it is correct.

- 150,581
- 18
- 184
- 329