Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The last sentence of the normative text that you cite reads as follows:</p> <blockquote> <p>If the virtual function call uses an explicit class member access and the object expression refers to the complete object of <code>x</code> or one of that object’s base class subobjects but not <code>x</code> or one of its base class subobjects, the behavior is undefined.</p> </blockquote> <p>This is, admittedly, rather convoluted. This sentence exists to restrict what functions may be called during construction in the presence of multiple inheritance.</p> <p>The example contains multiple inheritance: <code>D</code> derives from <code>A</code> and <code>B</code> (we'll ignore <code>V</code>, because it is not required to demonstrate why the behavior is undefined). During construction of a <code>D</code> object, both the <code>A</code> and <code>B</code> constructors will be called to construct the base class subobjects of the <code>D</code> object.</p> <p>When the <code>B</code> constructor is called, the type <em>of the complete object of <code>x</code></em> is <code>D</code>. In that constructor, <code>a</code> is a pointer to the <code>A</code> base class subobject of <code>x</code>. So, we can say the following about <code>a-&gt;f()</code>:</p> <ul> <li><p>The <em>object under construction</em> is the <code>B</code> base class subobject of a <code>D</code> object (because this base class subobject is the object currently under construction, it is what the text refers to as <code>x</code>).</p></li> <li><p>It uses <em>explicit class member access</em> (via the <code>-&gt;</code> operator, in this case)</p></li> <li><p>The type of <em>the complete object of <code>x</code></em> is <code>D</code>, because that is the most-derived type that is being constructed</p></li> <li><p>The <em>object expression</em> (<code>a</code>) refers to a <em>base class subobject</em> of the complete object of <code>x</code> (it refers to the <code>A</code> base class subobject of the <code>D</code> object being constructed)</p></li> <li><p>The base class subobject to which the <em>object expression</em> refers is not <code>x</code> and is not a base class subobject of <code>x</code>: <code>A</code> is not <code>B</code> and <code>A</code> is not a base class of <code>B</code>.</p></li> </ul> <p>Therefore, the behavior of the call is undefined, per the rule we started from at the beginning.</p> <blockquote> <p>Why is the last method call in <code>B::B</code> undefined? Shouldn't it just call <code>a.A::f</code>?</p> </blockquote> <p>The rule you cite states that when a constructor is called during construction, "the function called is the final overrider in the constructor’s class and not one overriding it in a more-derived class."</p> <p>In this case, the constructor's class is <code>B</code>. Because <code>B</code> does not derive from <code>A</code>, there is no final overrider for the virtual function. Therefore the attempt to make the virtual call exhibits undefined behavior.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload