<div dir="ltr"><div>I have a couple of questions regarding lifetime of objects in c and c++.</div><div><br></div><div>When I compile the following code and execute it, I get different results depending on the optimization level I specify on the command line.</div><div><br></div><div>$ cat t1.c</div><div>#include <stdio.h><br>int main(int ac, char** av) {<br>  int *p = 0;<br> label1:<br>  if (p) {<br>    printf("%d\n", *p);<br>    return 0;<br>  }<br><br>  int i = 999;<br>  if (ac != 2) {<br>    p = &i;<br>    goto label1;<br>  }<br>  return -1;<br>}</div><div><br></div><div><div>$ clang t1.c -O0 && ./a.out</div></div><div>999</div><div><div><br></div><div>$ clang t1.c -O1 && ./a.out</div><div>1</div></div><div><br></div><div>It looks like the difference is caused by the lifetime start/end marker inserted at -O1. clang inserts lifetime.start at the variable initialization and lifetime.end before the jump to label1. Because the goto's destination label1 is not in the lifetime range of variable "i", the content of "i" gets altered when printf is executed.</div><div><br></div><div>This seems like a mis-compile according to the C standard:</div><div><br></div>"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."<div><br></div><div>The block with which "i" is associated is the whole function, so "i" shouldn't be destroyed when the goto jumps back past its declaration.</div><div><br></div><div>Is my understanding correct? I discussed this with a couple of people and we all agreed that this looks like an UB as a C code.</div><div><br></div><div>What if the code is compiled as a c++ code? Is it still UB?</div><div><br></div><div>If the variable in question had a non-trivial destructor, it would probably be UB. In n3337 6.7, there is a c++ code snippet that shows a goto jumping back past the declaration of a variable of type class "X", and it states that the variable's destructor gets called when it goes out of scope. However, I'm not sure what the rules are for variables that are POD types. The standard says in 6.6 Jump Statements that the object gets destructed in such cases:</div><div><br></div>Transfer out of a loop, out of a block, or back past an initialized variable with automatic storage duration involves the destruction of objects with automatic storage duration that are in scope at the point transferred from but not at the point transferred to.<div><br></div><div>Does "destructed" simply mean a destructor is called? Or it means the content of the object is destroyed regardless of whether or nor it's a POD?</div></div>