Reputation: 38939
There is a lot of debate about the goto
command, this question is not about the rightness or wrongness of its use, but more simply a question of whether it ever actually creates different assembly.
I'm specifically looking at Visual Studio 2013, but an example in any compiler would be wonderful.
The scope of a label is the function it is in (§6.3.4). This implies that you can use
goto
to jump into and out of blocks. The only restriction is that you cannot jump past an initializer or an exception handler (§13.5).
One to the few sensible uses ofgoto
in ordinary code is to break out from a nested loop orswitch
-statement.
My question then: Is there any instance in which goto
still produces different assembly than what can already be accomplished by use of other control structures?
For example, this produces identical assembly:
auto r = rand();
auto a = 0;
for(auto i = rand(); i > 0; --i){
switch(r){
case 1:
++sum;
goto END;
case default:
sum += rand();
break;
}
}
sum++;
END:
To this non-goto
code:
auto r = rand();
auto b = false;
auto a = 0;
for(auto i = rand(); i > 0; --i){
switch(r){
case 1:
++sum;
b = true;
break;
case default:
sum += rand();
break;
}
if(b)break;
}
if(!b)sum++;
Upvotes: 1
Views: 125
Reputation: 52602
Here's my experience: I once had a bit of code that was extremely time critical. And it had a loop that iterated on average zero times (while (condition) ...) and the condition was almost always false. The compiler insisted on loop optimisations, moving things outside the loop - even when the loop wasn't executed at all, therefore slowing it down.
I tried to rewrite the loop using goto, hoping to confuse the optimiser enough to give up on optimising the code, and failed. gcc and clang optimise depending on the actual control flow, not depending on what C or C++ code you use.
Upvotes: 1