<div dir="ltr">On Mon, Sep 9, 2013 at 10:44 AM, Gabriel Dos Reis <span dir="ltr">&lt;<a href="mailto:gdr@axiomatics.org" target="_blank">gdr@axiomatics.org</a>&gt;</span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">Jeffrey Yasskin &lt;<a href="mailto:jyasskin@google.com">jyasskin@google.com</a>&gt; writes:<br>

<br>
| On Sun, Sep 8, 2013 at 9:48 PM, Gabriel Dos Reis &lt;<a href="mailto:gdr@axiomatics.org">gdr@axiomatics.org</a>&gt; wrote:<br>
| &gt; |     In fact, it is not at clear that either programmers or compilers want<br>
| &gt; |     a notion of &#39;object resuscitation&#39;.<br>
| &gt; |<br>
| &gt; |<br>
| &gt; | I don&#39;t know what you mean by &#39;resuscitation&#39; here. Can you elaborate?<br>
| &gt;<br>
| &gt; Resuscitation here refer to the idea that<br>
| &gt;<br>
| &gt;   &quot;there exists a set of times when objects&#39; lifetimes begin and end, and<br>
| &gt;    that set gives the program defined behavior, then the program has<br>
| &gt;    defined behavior&quot;<br>
| &gt;<br>
| &gt; If we don&#39;t have a uniquely defined point in time where the lifetime of<br>
| &gt; an object starts, that means that either it never started or it started<br>
| &gt; and ended multitple times.<br>
|<br>
| I think you&#39;ve misread Richard here. He didn&#39;t say &quot;a set of times<br>
<br>
</div>I am not sure but only Richard knows whether he meant to talk about a<br>
specific object&#39;s lifetime or the lifetimes of a collection of objects.<br>
<br>
If the latter, that is a very surprising way to tackle the issue since<br>
it does not appear to shed more light than the conversation about the<br>
lifetime of a given object.</blockquote><div><br></div><div>I did mean the latter.</div><div><br></div><div>One problem we face is that, for a given execution of a given program, the lifetime of a given object is not uniquely determined. And that&#39;s not a bug, it&#39;s a feature, and people rely on it. Consider this contrived example:</div>
<div><br></div><div>struct A { int x; int y; };</div><div>struct B { double d; };</div><div>static_assert(sizeof(A) == sizeof(B), &quot;&quot;);</div><div><br></div><div>int f() {</div><div>  alignas(A, B) char my_buffer[sizeof(A)];</div>
<div>  memcpy(my_buffer, data_from_network, sizeof(A)); // #1<br></div><div>  if (getch() == &#39;x&#39;) // #2</div><div>    return x + reinterpret_cast&lt;A*&gt;(my_buffer)-&gt;x; // #3</div><div>  else</div><div>    return x + reinterpret_cast&lt;B*&gt;(my_buffer)-&gt;d; // #4</div>
<div>}<br></div><div><br></div><div>[Under my interpretation of the current rules, and assuming the static_assert does not fire:]</div><div><br></div><div>In the case where the &#39;if&#39; condition is true, an object of type A at address &amp;my_buffer must have had its lifetime begin before line #1, and last until after line #3. And conversely, when the &#39;if&#39; condition is false, an object of type B at address &amp;my_buffer must have had its lifetime begin before line #1, and last until after line #4.</div>
<div><br></div><div>Both of these cases appear to have defined behavior, assuming the memcpy copies in a valid object representation for the chosen type: storage of the appropriate size and alignment was obtained for an object with trivial initialization ([basic.life] (3.8)p1), so the object&#39;s lifetime began. But by the time we reach line #2, we *do not know* whether there is an object of type A or an object of type B in my_buffer.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div class="im">| when an object&#39;s (singular, possessive) lifetimes begin and end&quot;; he<br>

| said &quot;a set of times when objects&#39; (plural, possessive) lifetimes<br>
| begin and end&quot;. I read that as a mapping of an object to the point in<br>
| time when its lifetime begins and the point in time when its lifetime<br>
| ends.<br>
<br>
</div>Here is the original paragraph:<br>
<br>
# More generally, my view of how the lifetime rules in [basic.life]p1 are<br>
# intended to work is:<br>
#  * If there exists a set of times when objects&#39; lifetimes begin and end, and<br>
# that set gives the program defined behavior, then the program has defined<br>
# behavior<br>
#  * Otherwise, the program has undefined behavior<br>
#<br>
# (In effect, the programmer chooses when lifetimes begin and end, and does not<br>
<div class="im"># need to write this intent in the source code.) Different choices of lifetime<br>
# beginning/end can only change whether the program has defined behavior, and<br>
# cannot imbue it with two different defined behaviors, so this approach seems to<br>
# be coherent, and (I think) captures what people expect.</div></blockquote><div><br></div><div>Right. Note that there can be multiple different mappings of object to lifetime, all of which give the program defined behavior (for instance, we don&#39;t know exactly when the object&#39;s lifetime starts in the above example code). We have a fundamental coherence property: if there are multiple different such mappings with defined behavior, all of them must have the *same* defined behavior.</div>
</div></div></div>