In my mind, always, definition means storage allocation.
In the following code, int i
allocates a 4-byte (typically) storage on program stack and bind it to i
, and i = 3
assigns 3 to that storage. But because of goto
, definition is bypassed which means there is no storage allocated for i
.
I heard that local variables are allocated either at the entry of the function (f()
in this case) where they reside, or at the point of definition.
But either way, how can i
be used while it hasn't been defined yet (no storage at all)? Where does the value three assigned to when executing i = 3
?
void f()
{
goto label;
int i;
label:
i = 3;
cout << i << endl; //prints 3 successfully
}
The control of flow has nothing to do with variable's storage which is reserved at compile time by the compiler.
The
goto
statement only effects the dynamic initialization of the object. For built-in types and POD types, it doesn't matter, for they can remain uninitialized. However, for non-POD types, this would result in compilation error. For example see thisError:
See here : http://ideone.com/p6kau
In this example
A
is a non-POD type because it has user-defined constructor, which means the object needs to be dynamically initialized, but since thegoto
statement attempts to skip this, the compiler generates error, as it should.Please note that objects of only built-in types and POD types can remain uninitialized.
The definition of a variable DOES NOT allocate memory for the variable. It does tell the compiler to prepare appropriate memory space to store the variable though, but the memory is not allocated when control passed the definition.
What really matters here is initialization.
Definitions are not executable code. They are just instructions to the compiler, letting it know the size and the type of the variable. In this sense, the definition is not bypassed by the
goto
statement.If you use a class with a constructor instead of an
int
, the call of the constructor would be bypassed by thegoto
, but the storage would be allocated anyway. The class instance would remain uninitialized, however, so using it before its definition/initialization line gets the control is an error.This is not correct. The storage for the variable is reserved by the compiler when it creates the stack-layout for the function. The
goto
just bypasses the initialization. Since you assign a value before printing, everything is fine.Your code is fine. The variable lives wherever it would live had the
goto
not been there.Note that there are situations where you can't jump over a declaration:
The position of the declaration of
i
is irrelevant to the compiler. You can prove this to yourself by compiling your code withint i
before thegoto
and then after and comparing the generated assembly:The only difference in this case is the source file name (
.file
) reference.