<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 6, 2014 at 3:44 PM, Richard Smith <span dir="ltr">&lt;<a href="mailto:richardsmith@google.com" target="_blank">richardsmith@google.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 dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div class="im">On Mon, Jan 6, 2014 at 10:22 AM, Jason Merrill <span dir="ltr">&lt;<a href="mailto:jason@redhat.com" target="_blank">jason@redhat.com</a>&gt;</span> wrote:<br>

</div><div class="im"><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div>On 01/06/2014 04:26 AM, Fabio Fracassi wrote:<br>
&gt; if it is not (legal): could we make it legal or would we run afoul of<br>
&gt; the aliasing rules?<br>
<br>
</div>The access is not allowed by the aliasing rules in 3.10.  But it seems<br>
that this would be:<br>
<div><br>
struct B {<br>
   int i;<br>
};<br>
<br>
struct D {<br>
</div>   B bmem;<br>
   void foo() { /* access bmem.i */ }<br>
};<br>
<br>
B b;<br>
reinterpret_cast&lt;D&amp;&gt;(b).foo();<br>
<br>
because B is a non-static data member of D, and 9.2/19 guarantees that<br>
the address of D::bmem is the same as the address of the D object.</blockquote><div><br></div></div><div>How is that fundamentally different? 9.3.1/2 makes that UB too, if &#39;reinterpret_cast&lt;D&amp;&gt;(b)&#39; does not refer to an object of type &#39;b&#39;.</div>
</div></div></div></blockquote><div><br></div><div>... an object of type &#39;D&#39;. Sorry!</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">
<div class="gmail_extra"><div class="gmail_quote"><div>And within D::foo, the implicit this-&gt;bmem would have the same problem.</div>
<div><br></div><div><br></div><div>If I might play devil&#39;s advocate for a moment...</div><div><br></div><div>  struct B { int i; };</div><div>  struct D : B {</div><div>    void foo();</div><div>  };</div><div><br></div>

<div>  B b;</div><div><br></div><div>I claim this line starts the lifetime of an object of type D. Per [basic.life]p1, the lifetime of an object of type &#39;D&#39; begins when storage with the proper alignment and size for type T is obtained (which &quot;B b&quot; happens to satisfy). The object does not have non-trivial initialization, so the second bullet does not apply.</div>

<div><br></div><div>(This is the same argument that makes this valid:</div><div><br></div><div>  D *p = (D*)malloc(sizeof(D));</div><div>  p-&gt;foo();</div><div><br></div><div>... so any counterargument will need to explain why the two cases are fundamentally different.)</div>

<div><br></div><div>Then:</div><div><br></div><div>  reinterpret_cast&lt;D&amp;&gt;(b).foo();</div><div><br></div><div>... is valid, because the cast produces the same memory address, and that memory address contains an object of type &#39;D&#39; (as claimed above).</div>

</div></div></div>
</blockquote></div><br></div></div>