Does the following piece of code constitute undefined behaviour, since I am jumping before the variable declaration and using it via a pointer? If so, are there differences between the standards?
int main() {
int *p = 0;
label1:
if (p) {
printf("%d\n", *p);
return 0;
}
int i = 999;
p = &i;
goto label1;
return -1;
}
There is no undefined behavior in your program.
goto
statement has two constraints:
(c11, 6.8.6.1p1) "The identifier in a goto statement shall name a label located somewhere in the enclosing function. A goto statement shall not jump from outside the scope of an identifier having a variably modified type to inside the scope of that identifier."
that you are not violating and there is no other shall requirements outside constraints.
Note that it is the same (in the sense there are no extra requirements) in c99 and c90. Of course in c90, the program would not be valid because of the mix of declaration and statements.
Regarding the lifetime of i
object when accessed after the goto
statement, C says (see my emphasis, the other copied sentences in the following paragraph would be interesting for a more tricky program):
(c11, 6.2.4p6) "For such an object that does not have a variable length array type, its lifetime extends from entry into the block with which it is associated until execution of that block ends in any way. [...] If the block is entered recursively, a new instance of the object is created each time. [...] If an initialization is specified for the object, it is performed each time the declaration or compound literal is reached in the execution of the block; otherwise, the value becomes indeterminate each time the declaration is reached."
That means, i
is still alive when *p
is read; no object is accessed outside its lifetime.