<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div><blockquote type="cite" class=""><div class="">On Jul 20, 2016, at 12:13 PM, Akira Hatanaka <<a href="mailto:ahatanak@gmail.com" class="">ahatanak@gmail.com</a>> wrote:</div><div class=""><div dir="ltr" class="">On Wed, Jul 20, 2016 at 12:01 PM, Richard Smith <span dir="ltr" class=""><<a href="mailto:richard@metafoo.co.uk" target="_blank" class="">richard@metafoo.co.uk</a>></span> wrote:<br class=""><div class="gmail_extra"><div class="gmail_quote"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""><div class="h5">On Wed, Jul 20, 2016 at 11:24 AM, Akira Hatanaka <span dir="ltr" class=""><<a href="mailto:ahatanak@gmail.com" target="_blank" class="">ahatanak@gmail.com</a>></span> wrote:<br class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="">I have a couple of questions regarding lifetime of objects in c and c++.</div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">$ cat t1.c</div><div class="">#include <stdio.h><br class="">int main(int ac, char** av) {<br class=""> int *p = 0;<br class=""> label1:<br class=""> if (p) {<br class=""> printf("%d\n", *p);<br class=""> return 0;<br class=""> }<br class=""><br class=""> int i = 999;<br class=""> if (ac != 2) {<br class=""> p = &i;<br class=""> goto label1;<br class=""> }<br class=""> return -1;<br class="">}</div><div class=""><br class=""></div><div class=""><div class="">$ clang t1.c -O0 && ./a.out</div></div><div class="">999</div><div class=""><div class=""><br class=""></div><div class="">$ clang t1.c -O1 && ./a.out</div><div class="">1</div></div><div class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">This seems like a mis-compile according to the C standard:</div><div class=""><br class=""></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 class=""><br class=""></div><div class="">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 class=""><br class=""></div><div class="">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></blockquote><div class=""><br class=""></div></div></div><div class="">This seems to contradict what you just said. In C, this example appears to have defined behavior, and we're miscompiling it.</div><span class=""><div class=""> </div></span></div></div></div></blockquote><div class=""><br class=""></div><div class="">Ah right. It's not UB in C but I wasn't sure whether it's UB in C++.</div><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><span class=""><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="">What if the code is compiled as a c++ code? Is it still UB?</div></div></blockquote><div class=""><br class=""></div></span><div class="">In C++, I'm confident that this is intended to be undefined behavior, but the standard does not appear to clearly specify that. I've filed a core issue.</div><span class=""><div class=""><br class=""></div></span></div></div></div></blockquote><div class=""><br class=""></div><div class="">OK, this is a mis-compile only when it's compiled as a C code then.</div></div></div></div></div></blockquote><div><br class=""></div>I agree with this analysis.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><div class=""> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="gmail_extra"><div class="gmail_quote"><span class=""><div class=""></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr" class=""><div class="">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 class=""><br class=""></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 class=""><br class=""></div><div class="">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>
</blockquote></span></div><br class=""></div></div>
</blockquote></div><br class=""></div></div>
</div></blockquote></div><br class=""></body></html>