In languages like C, goto is particularly useful when you're cycle-shaving and don't trust the compiler's optimizer to do the right thing. This is seen regularly in the Linux kernel source.
Consider the following snippet:
x = (*ptr);
if (x==0) {
*ptr = -1;
failures++;
return;
}
*ptr2 = x;
...
return;
Now assume that (x==0) is the exception and not the common case. When this is boiled down to machine instructions, without any code reorganization or reordering, it would look something like this on a RISC-ish machine:
ld R1, (R2);
bnz R1, a;
sub R1, R0, 1;
st (R2), R1;
add R3, R3, 1;
RETURN; # macro handling the stack frame etc...
a:
st (R4), R1;
...
RETURN;
See the problem? That bnz instruction will usually be taken; if the processor has a simple pipeline, then the sub inside the "exception" code block will already have been fetched and will have to be invalidated while the target instruction is fetched. (Granted, some more involved branch prediction techniques can reduce this effect, but even then they usullay rely upon a warm cache to make the right choice.)
What would really be great is if the machine code looked like this:
ld R1, (R2);
bez R1, b;
st (R4), R1;
....
RETURN;
b:
sub R1, R0, 1;
st (R2), R1;
add R3, R3, 1;
RETURN;
See what we've done? The branch is now not taken in the common case, thus the instruction pre-fetch of the store is allowed to proceed and execute without a stall. Even better.
But what if we don't trust our compiler to do this little trick for us? Well, we can write our code in a way that maps to this construct directly. We have two options.
The first would look something like this:
x = (*ptr);
if (x!=0) {
*ptr2 = x;
...
return;
} else {
*ptr = -1;
failures++;
return;
}
This is good form if we have only one or maybe two such predicates in a code block. However, if there is a series of five of them, then the nesting quickly obfuscates the intent of your code.
The other alternative looks something like this:
x = (*ptr);
if (x==0)
goto problem;
*ptr2 = x;
...
return;
problem:
*ptr = -1;
failures++;
return;
Ah, a hacker's view of paradise. The meaning is clear - code is speech. The optimal strategy for the compiler is trivial. And we have prided ourselves on showing our middle school computer class teacher that the mighty and venerable goto does indeed have its place in the toolkit of the modern code jockey.
Use knowledgably, sparingly, and tastefully.