<div dir="ltr">On Mon, Sep 9, 2013 at 2:54 PM, 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:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">Richard Smith &lt;<a href="mailto:richardsmith@google.com">richardsmith@google.com</a>&gt; writes:<br>

<br>
| On Mon, Sep 9, 2013 at 10:44 AM, Gabriel Dos Reis &lt;<a href="mailto:gdr@axiomatics.org">gdr@axiomatics.org</a>&gt; wrote:<br>
|<br>
|     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;<br>
|     wrote:<br>
|     | &gt; |     In fact, it is not at clear that either programmers or compilers<br>
|     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<br>
|     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,<br>
|     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>
|     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.<br>
|<br>
|<br>
| I did mean the latter.<br>
|<br>
| One problem we face is that, for a given execution of a given program, the<br>
| lifetime of a given object is not uniquely determined.<br>
<br>
</div></div>I think this is where we differ, at a very fundamental level.<br>
Truth to be told, this is the first time that I see this suggestion.<br>
<br>
In my discussions with Bjarne, I never got the impression that this is<br>
what he conceived or wanted.  But, he will sure shime in...<br>
<div><div class="h5"><br>
| And that&#39;s not a bug,<br>
| it&#39;s a feature, and people rely on it. Consider this contrived example:<br>
|<br>
| struct A { int x; int y; };<br>
| struct B { double d; };<br>
| static_assert(sizeof(A) == sizeof(B), &quot;&quot;);<br>
|<br>
| int f() {<br>
|   alignas(A, B) char my_buffer[sizeof(A)];<br>
|   memcpy(my_buffer, data_from_network, sizeof(A)); // #1<br>
|   if (getch() == &#39;x&#39;) // #2<br>
|     return x + reinterpret_cast&lt;A*&gt;(my_buffer)-&gt;x; // #3<br>
|   else<br>
|     return x + reinterpret_cast&lt;B*&gt;(my_buffer)-&gt;d; // #4<br>
| }<br>
|<br>
| [Under my interpretation of the current rules, and assuming the static_assert<br>
| does not fire:]<br>
|<br>
| In the case where the &#39;if&#39; condition is true, an object of type A at address &amp;<br>
| my_buffer must have had its lifetime begin before line #1, and last until after<br>
| line #3. And conversely, when the &#39;if&#39; condition is false, an object of type B<br>
| at address &amp;my_buffer must have had its lifetime begin before line #1, and last<br>
| until after line #4.<br>
|<br>
| Both of these cases appear to have defined behavior, assuming the memcpy copies<br>
| in a valid object representation for the chosen type: storage of the<br>
| appropriate size and alignment was obtained for an object with trivial<br>
| initialization ([basic.life] (3.8)p1), so the object&#39;s lifetime began. But by<br>
| the time we reach line #2, we *do not know* whether there is an object of type<br>
| A or an object of type B in my_buffer.<br>
|<br>
|<br>
|     | 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>
|     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,<br>
|     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<br>
|     not<br>
|     # need to write this intent in the source code.) Different choices of<br>
|     lifetime<br>
|     # beginning/end can only change whether the program has defined behavior,<br>
|     and<br>
|     # cannot imbue it with two different defined behaviors, so this approach<br>
|     seems to<br>
|     # be coherent, and (I think) captures what people expect.<br>
|<br>
|<br>
| Right. Note that there can be multiple different mappings of object to<br>
| lifetime, all of which give the program defined behavior (for instance, we<br>
| don&#39;t know exactly when the object&#39;s lifetime starts in the above example<br>
| code). We have a fundamental coherence property: if there are multiple<br>
| different such mappings with defined behavior, all of them must have the *same*<br>
| defined behavior.<br>
<br>
</div></div>This coherence problem exists only if you believe that the C++ object<br>
model was designed to have such multiple mappings for object lifetime.  This<br>
explains why we have been talking past each other until now :-)</blockquote><div><br></div><div>Indeed :-)</div><div><br></div><div>The C and C++ object models have never been precisely defined to the point where users and implementors largely agree on how they work (and the validity of my example code is within the area of dispute). Fixing that is part of the remit of this SG, as I understand things. So please take my description above as part of a proposal for how to resolve the various issues with the object model. (For a more complete proposal, we also need to precisely define the semantics of pointers and references -- I do have a semantic model that covers those too, but haven&#39;t yet written the requisite paper explaining it.)</div>
<div><br></div><div>Sorry that we were talking past each other!</div></div></div></div>