That's not much different from:
void fn(int i) {
printf("%d\n",i);
}
What's the value of i here? And this can be called from anywhere in an
application, not just the current function.
Like Stephan, you've pretty much missed the point of my example, so let
me expand on it.
I'm tasked with tracing the flow of control within a single function to
determine where a particular bug occurs. This bug has to do with the
output of a particular variable (I expect it to be 5 at some point, but
it never is). So I start from the output statement:
i = 5;
label: printf("%d\n", i);
Okay. Assuming direct flow of control, I would expect the printf statement
to output 5 (after all, the variable is set in the statement immediately
before the printf call), but the presence of the label implies that the flow
of control *isn't* direct; there is *at least* one way to reach that print
statement without going through the "i = 5;" statement. So I look for any
occurrences of "goto label;" and find the following:
void foo()
{
int i = 0;
...
i = 5;
label:
printf("%d\n", i);
...
i = bar();
goto label;
...
}
Huh. So I find a line that branches back to the printf statement after
i is set to the result of bar(), but why am I not getting a 5 for output?
Expanding my search, I find the following:
void foo()
{
int i = 0;
...
goto bletch;
...
i = 5;
label:
printf("%d\n", i);
...
bletch:
...
i = bar();
goto label;
...
}
Yuck. So, it looks like that "i = 5;" statement was completely bypassed;
the code doesn't do what I expected it to do from a cursory inspection.
Yeah, sure, I can build a debug version and run it through gdb to figure out
how we get to that print statement. I can spend time stepping through a
function line by goddamned line looking for a stupid bug because it's not
like I have anything else to do.
Is that example completely contrived? I wish I could say it was. It was
inspired by real code I've had to review in the past (except that "foo" was
several *thousand* lines long and there were 12 or 13 more labels with
gotos branching all over the goddamned place).
Now, this was bad code without the presence of the gotos, but the
gotos made a bad situation impossible. The original author couldn't be
bothered to factor common code out into subroutines; he *simulated* them
by using gotos, but made such a hash of it that we couldn't fix one
execution path without breaking another.
My *point* was that as soon as you see a labeled statement, you can't make
any assumptions about the order in which that statement is executed relative
to the statement(s) immediately preceding it, and yes, THAT MATTERS. You
can't say anything about how the function works without tracing through every
possible permutation of gotos. The bigger the function, the harder that
task gets.