<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">2017-08-11 13:47 GMT+02:00 Jens Maurer <span dir="ltr">&lt;<a href="mailto:Jens.Maurer@gmx.net" target="_blank">Jens.Maurer@gmx.net</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><span class="gmail-">On 08/11/2017 09:58 AM, Andrzej Krzemienski wrote:<br>
&gt; Hi SG12 Members,<br>
&gt;<br>
</span>&gt; I already asked this question in ISO C++ Standard - Discussion  (<a href="https://groups.google.com/a/isocpp.org/forum/?fromgroups=#%21topic/std-discussion/UbROFU6Fs0E" rel="noreferrer" target="_blank">https://groups.google.com/a/<wbr>isocpp.org/forum/?fromgroups=#<wbr>!topic/std-discussion/<wbr>UbROFU6Fs0E</a> &lt;<a href="https://groups.google.com/a/isocpp.org/forum/?fromgroups=#%21topic/std-discussion/UbROFU6Fs0E" rel="noreferrer" target="_blank">https://groups.google.com/a/<wbr>isocpp.org/forum/?fromgroups=#<wbr>%21topic/std-discussion/<wbr>UbROFU6Fs0E</a>&gt;), but maybe this list is better suited.<br>
<span class="gmail-">&gt;<br>
&gt; UB-sanitizer reports a runtime error for the following program:<br>
&gt;<br>
&gt; ```<br>
&gt; struct B;<br>
&gt;<br>
&gt; struct I {<br>
&gt;   virtual void f() {}; // &lt;- virtual<br>
&gt; };<br>
&gt;<br>
&gt; struct A : I {<br>
&gt;   A();<br>
&gt; };<br>
&gt;<br>
&gt; struct B : A {<br>
&gt; };<br>
&gt;<br>
&gt; A::A() { *static_cast&lt;B*&gt;(this); } // &lt;- UB in static_cast<br>
&gt;<br>
&gt; int main()<br>
&gt; {<br>
&gt;   B{};<br>
&gt; }<br>
&gt; ```<br>
&gt;<br>
&gt; My question: is UB-sanitizer correct? Is this a UB according to the standard? And if so, could you point me to the relevant sections?<br>
<br>
</span>The dereference here is immaterial; it just converts a pointer to an lvalue,<br>
neither of which accesses the pointed-to value per se.<br>
<br>
The conversion happens while A and B are being constructed, and we have<br>
special rules in 15.7 [class.cdtor] for that.  Of particular interest<br>
is p2, which discusses conversions from B* to A*, but 8.2.9 [expr.static.cast]<br>
indirectly refers to that case when discussing the A* to B* case.<br>
<br>
Both the construction of B and A have started at the point in question,<br>
so it seems to me the pointer conversion is, in fact, valid.<br></blockquote><div><br></div><div>Thanks for your analysis. Interestingly, I have now arrived at the opposite conclusion, based on [expr.static.cast]/p11 and [class.dtor]/p16, and some interpolation of my own. Let me share my reasoning, and tell me what you make of it.<br><br>[class.cdtor]/p2 talks about the upcast, so I would rather go with [expr.static.cast]/p11 which talks about the downcast. The latter says the downcast is UB-free if the casted-from object O is casted to an object that contains O as its subobject. Term &quot;object&quot; implies a relation to run-time (life-time), there is just the question whether we mean &quot;object lifetime (after non-delegating constructor finishes and before the destructor starts) or the &quot;extended object time&quot; (after constructor starts and before destructor finishes).<br><br></div><div>Now, [class.dtor]/p16 says, &quot;Once a destructor is invoked for an object, the object no longer exists&quot;. This &quot;exists&quot; I find applicable to the definition of class.cdtor]/p2. If we were considering the same downcast in the *destructor* of  A, I would have a clear answer. Now, there is no similar statement when the object starts to &quot;exist&quot;, but by analogy to destructor, I would conclude that it starts to exist when the constructor finises. Untill then, there is no object B in existence and therefore the the static_cast condition that &quot;the casted-from object O is casted to an object that contains O as its subobject&quot; is not satisfied.<br><br></div><div>Is the above reasoning correct?<br><br></div><div>Regards,<br></div><div>&amp;rzej;<br></div><div><br></div></div><br></div></div>