<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On 17 January 2014 15:19, Gabriel Dos Reis <span dir="ltr">&lt;<a href="mailto:gdr@microsoft.com" target="_blank">gdr@microsoft.com</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">| From what I&#39;ve learned in this thread, the (rough) intended C++ model for<br>
| PODs (assuming memory of the right size/alignment) would seem to be &quot;the<br>
| lifetime of a B starts when you write to the memory as a B, and ends when you<br>
| free the memory or write to the memory as different type.&quot; [Disclaimer: I&#39;m<br>
| not sure if &quot;read from the memory as a B&quot; also starts lifetime.&quot;]<br>
<br>
</div>that would be close to what C does with effective types.<br>
<div class="im"><br>
| I think we can do better,<br>
<br>
</div>Same here.<br>
<div class="im"><br>
| but it seems like that&#39;s the (rough) intent of the<br>
| status quo, leaving aside the question of whether the wording actually says<br>
| that.<br>
|<br>
|<br>
| *If* that is the (rough) intent, then in:<br>
|<br>
|<br>
|         void *p = malloc(sizeof(B)); // 1<br>
|<br>
|         B* pb = (B*)p; // 2<br>
|<br>
|         pb-&gt;i = 0; // 3<br>
|<br>
|         short* ps = (short*)p; // 4<br>
|         *ps = 0; // 5<br>
|<br>
|         free(p); // 6<br>
|<br>
|<br>
|<br>
|<br>
| I assume that the reasoning would be that:<br>
|<br>
</div>| *     line 3 starts the lifetime of a B (we&#39;re writing to the bits of a B member,<br>
| not just any int)<br>
<br>
line 3 does not write as a B, so it wouldn&#39;t count -- just like in C.<br></blockquote><div><br></div><div>Would that not give &#39;pb-&gt;i = 0&#39; undefined behavior, because &#39;pb&#39; does not, in fact, point to a B object?</div>
<div><br></div><div><br></div><div>The only clear governing rule I can find is 3.8/5, but that only applies if the storage ever actually contains a B object. Consider:</div><div><br></div><div>  void *p = malloc(sizeof(B));</div>
<div>  B *pb = (B*)p;</div><div>  pb-&gt;i = 0;</div><div>  // ...</div><div>  new (p) B;</div><div><br></div><div>In this example, &quot;pb-&gt;i = 0&quot; has undefined behavior, because we performed member access on a pointer that points to storage where a B object will later be constructed. It seems strange that the definedness of &#39;pb-&gt;i = 0&#39; would depend on how the storage is used later.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
| *     line 5 ends the lifetime of that B and begins the lifetime of a short<br>
| *     line 6 ends the lifetime of that short<br>
<br>
Agreed.<br>
<div class="im"><br>
| Again ignoring whether this is desirable, is that (roughly) the intent of the<br>
| current wording?<br>
<br>
</div>Almost: we never started the lifetime of a B object.<br>
<div class="im"><br>
| If yes, does the wording express it (a) accurately and (b) clearly?<br>
<br>
</div>My understanding is &quot;no&quot; for both.</blockquote><div><br></div><div>Hear, hear =)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">

| Finally, regardless of the above answer, do we want to change anything about<br>
| the legality or semantics of the above type-punning code, such as possibly<br>
| having a &quot;type-safe mode&quot; where such code is somehow not allowed unless in<br>
| an &quot;extern &quot;C-compat&quot;&quot; block or something?<br>
<br>
</div>This is a good question!  Which definitely needs a paper :-)<br>
<br>
My view is that if the storage isn&#39;t declared or accessed as a B, then it isn&#39;t a B .<br></blockquote><div><br></div><div>It seems you don&#39;t consider member access as a B to qualify here. Is that your intent?</div>
</div></div></div>