<html><head><meta http-equiv="Content-Type" content="text/html charset=windows-1252"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>On May 9, 2013, at 9:22 PM, Nick Lewycky <<a href="mailto:nlewycky@google.com">nlewycky@google.com</a>> wrote:</div><blockquote type="cite"><div dir="ltr">On 9 May 2013 19:13, John McCall <span dir="ltr"><<a href="mailto:rjmccall@apple.com" target="_blank">rjmccall@apple.com</a>></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; position: static; z-index: auto; ">


<div>This is not how I understand the [basic.life] rules.  The question is whether a pointer value, reference, or name is formally forwarded to point to the new object.  Because the dynamic type is different, the pointer value held in 'p' is not updated.  Copying that value into 'q' does not change the fact that the pointer value still refers to a non-existent object.</div></blockquote><div><br></div><div><div class="gmail_quote">I'm actually okay with the simple copy not forming a new object pointer. However, "Base *q = reinterpret_cast<Base*>(p);" really ought to.</div></div></div></div></div></blockquote><div><br></div>Yes, I agree that it ought to.</div><div><br><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>


<div class="gmail_quote"></div></div></div><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; position: static; z-index: auto; ">


It is unclear what, exactly, under the rules constitutes forming a valid pointer to the newly-constructed object except using the result of the new-expression itself.  I think an explicit cast might, ignoring all "object-ness" of the source pointer and simply treating it formally as a pointer to some storage that you are casting to the type of an object stored there?<br>


</blockquote><div><br></div><div>I want to make optimizations to the program that people can't object to through a cursory reading of the standard, which is made difficult by the standard being contradictory on many relevant points here. Ultimately I've chosen to be very liberal about what I'm allowing to be considered a newly formed valid pointer.</div></div></div></div></blockquote><div><br></div><div>Being conservative is fair.  My point was just that it has absolutely nothing to do with being held in a named pointer variable.  Also, this is C++, so you almost certainly need to be able to track the object-ness of values across inlining in order to have much hope of meaningful optimization.  And potentially not just across inlining, but through memory — who actually allocates polymorphic values and doesn't use smart pointers these days?</div><div><br></div><blockquote type="cite"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">


<div>BTW, Richard came up with a wonderful example. What do you make of this?:<br></div><div><div style=""><br></div><div style="">  char alignas(A, B) buffer[max(sizeof(A), sizeof(B))];</div><div style="">  A *a = reinterpret_cast<A*>(buffer);</div>

<div style="">  B *b = reinterpret_cast<B*>(buffer);<br></div><div style="">  new(buffer) A;</div><div style="">  a->vfn();</div><div style="">  new(buffer) B;</div><div style="">  b->vfn();</div><div style=""><br></div><div style="">

Valid?</div></div></div></div></div></blockquote><div><br></div></div><div>Let's answer a simpler question.  Why is this valid?</div><div><br></div><div>    A *a = reinterpret_cast<A*>(buffer);</div><div><div>    new(buffer) A;</div><div>    a->vfn();</div><div><br></div><div>My initial interpretation is that the initial value of 'a' is a type-punned pointer that refers to an object of type char[n].  The lifetime of that object ends when we reuse its storage for a new object of type A.  (This is okay to do to any type;  additionally, since the char[n] object does not have a non-trivial destructor, we are not required to put a char[n] object back before it goes out of scope.)  This leaves the name 'buffer' referring only to allocated storage.  The lifetime of the A object begins after the constructor completes.  'a' does not automatically refer to the new object because the type of the object it refers to does not match the type of the object now created there.  So, what's the theory that allows us to use 'a' here as if it referred to the new object?</div><div><br></div><div>To be clear, I think we obviously have to permit both of these examples.</div><div><br></div><div>The only additional complication with Richard's example is that yet another object comes into existence.  I don't see that as fundamentally changing anything.</div><div><br></div><div>John.</div></div></body></html>