Possible Duplicate:
Is it ever worthwhile using goto?
In a recent article, Andrew Koenig writes:
When asked why goto statements are harmful, most programmers will say something like "because they make programs hard to understand." Press harder, and you may well hear something like "I don't really know, but that's what I was taught." For that reason, I'd like to summarize Dijkstra's arguments.
He then shows two program fragments, one without a goto and and one with a goto:
if (n < 0)
n = 0;
Assuming that n is a variable of a built-in numeric type, we know that after this code, n is nonnegative.
Suppose we rewrite this fragment:
if (n >= 0) goto nonneg;
n = 0;
nonneg: ;
In theory, this rewrite should have the same effect as the original. However, rewriting has changed something important: It has opened the possibility of transferring control to nonneg from anywhere else in the program.
I emphasized the part that I don't agree with. Modern languages like C++ do not allow goto to transfer control arbitrarily. Here are two examples:
You cannot jump to a label that is defined in a different function.
You cannot jump over a variable initialization.
Now consider composing your code of tiny functions that adhere to the single responsibility principle:
int clamp_to_zero(int n)
{
if (n >= 0) goto n_is_not_negative:
n = 0;
n_is_not_negative:
return n;
}
The classic argument against the goto statement is that control could have transferred from anywhere inside your program to the label n_is_not_negative, but this simply is not (and was never) true in C++. If you try it, you will get a compiler error, because labels are scoped. The rest of the program doesn't even see the name n_is_not_negative, so it's just not possible to jump there. This is a static guarantee!
Now, I'm not saying that this version is better then the one without the goto, but to make the latter as expressive as the first one, we would at least have to insert a comment, or even better yet, an assertion:
int clamp_to_zero(int n)
{
if (n < 0)
n = 0;
// n is not negative at this point
assert(n >= 0);
return n;
}
Note that you basically get the assertion for free in the goto version, because the condition n >= 0 is already written in line 1, and n = 0; satisfies the condition trivially. But that's just a random observation.
It seems to me that "don't use gotos!" is one of those dogmas like "don't use multiple returns!" that stem from a time where the real problem were functions of hundreds or even thousand of lines of code.
So, do we still have a case against the goto statement, other than that it is not particularly useful? I haven't written a goto in at least a decade, but it's not like I was running away in terror whenever I encountered one. 1 Ideally, I would like to see a strong and valid argument against gotos that still holds when you adhere to established programming principles for clean code like the SRP. "You can jump anywhere" is not (and has never been) a valid argument in C++, and somehow I don't like teaching stuff that is not true.
1: Also, I have never been able to resurrect even a single velociraptor, no matter how many gotos I tried :(