How does the compiler implement the rule stated in the last statement of §12.6.2/7 (C++11)?

48 views
Skip to first unread message

Belloc

unread,
Mar 4, 2015, 7:07:08 PM3/4/15
to std-dis...@isocpp.org
From the snippet below (see live example) one can see that when main() instantiates b, the code initializes b.i = 1 as B is the most derived class of the virtual base A and this follows exactly what is prescribed in this statement in §12.6.2/7 (C++11):

"A mem-initializer where the mem-initializer-id denotes a virtual base class is ignored during execution of a constructor of any class that is not the most derived class."

However when c is instantiated the code ignores the mem-initializer A(1) in B's default constructor, because B is not the most derived class for this object, and this is also in agreement with the statement in §12.6.2/7.

#include <iostream>


using std::cout;
using std::endl;


struct A
{
   
int i;
    A
(int i) : i(i) { cout << "A(int) i = " << i << endl; }
};


struct B : virtual A
{
    B
() : A(1) { cout << "B() i = " << i << endl; }
};


struct C : B
{
    C
() : A(10), B() { cout << "C() i = " << i << endl; }
};




int main()
{
    B b
;
    cout
<< b.i << endl;
    C c
;
    cout
<< c.i << endl;
}



I was just wondering how the compiler might implement this trick?

Richard Smith

unread,
Mar 4, 2015, 7:32:07 PM3/4/15
to std-dis...@isocpp.org
Here are two implementation techniques used by real compilers and ABIs:

1) Emit two versions of each constructor: a "complete object constructor" that constructs virtual bases, and a "subobject constructor" that does not. (In practice, the complete object constructor usually just constructs virtual bases then invokes the subobject constructor, but in some cases (varargs constructors) that's not possible and instead two complete copies of the constructor are emitted.) This is what the Itanium C++ ABI does.

2) Give all constructors for a class with virtual bases a secret additional bool parameter indicating whether those virtual bases should be constructed. Implicitly pass 'false' when constructing base class subobjects and 'true' otherwise. This is what the MS C++ ABI does.

Belloc

unread,
Mar 5, 2015, 7:15:25 AM3/5/15
to std-dis...@isocpp.org
Pretty clever. Many thanks for the small but insightful answer.
Reply all
Reply to author
Forward
0 new messages