Topic: Virtual Base Initialisation


Author: maxtal@extro.ucc.su.OZ.AU (John MAX Skaller)
Date: 7 Feb 93 17:01:41 GMT
Raw View
Help! I cant figure out how virtual bases get initialised in
real implementations.

As far as I can figure, there has to be a switch in the base
to prevent duplicate initialisation. But since any class
might be a virtual base, that implies even C struct type
classes (without a vtble pointer) must have the switch,
destroying any possibility of C compatibility.

Am I right? What is actually done by real implementations?

BTW: I'm asking because I'm trying to figure out a way to
improve the current mechanism for initialistion of virtual bases.
But now I cant figure how they're initialised at all!

--
;----------------------------------------------------------------------
        JOHN (MAX) SKALLER,         maxtal@extro.ucc.su.oz.au
 Maxtal Pty Ltd, 6 MacKay St ASHFIELD, NSW 2131, AUSTRALIA
;------ SCIENTIFIC AND ENGINEERING SOFTWARE ---ph:  2 799 8223 --------




Author: steve@taumet.com (Steve Clamage)
Date: Wed, 10 Feb 1993 18:48:07 GMT
Raw View
maxtal@extro.ucc.su.OZ.AU (John MAX Skaller) writes:

>Help! I cant figure out how virtual bases get initialised in
>real implementations.

>As far as I can figure, there has to be a switch in the base
>to prevent duplicate initialisation. But since any class
>might be a virtual base, that implies even C struct type
>classes (without a vtble pointer) must have the switch,
>destroying any possibility of C compatibility.

The usual implementation works this way:

If a class has a virtual base class, each constructor for that
class has an extra (hidden) parameter which contains a flag
telling it whether it is being called for the most-derived object.
If so, the constructor invokes the virtual base class constructors,
otherwise it does not.

The compiler always has enough information to know whether a
constructor has the extra parameter, and how to set it if so.
The hidden parameter, as with "this", usually does not show up in
the name mangling.

Example:

 class vbase { ... vbase(){...}; };
 class base : public virtual vbase { ... base(){...}; };
 class deriv : public base { ... deriv(){...}; };
 void foo()
 {
     base b;
     deriv d;
     ...
 }

The compiler will generate code like this pseudo-code:

 base::base(base* this, char flag) // two hidden parameters
 {
     if( flag ) vbase::vbase(this);
     ...
 }
 deriv::deriv(deriv* this, char flag) // two hidden parameters
 {
     if( flag ) vbase::vbase(this);
     base::base(this, 0); // base will not invoke vbase ctor
     ...
 }
 void foo()
 {
     base b;  base::base(&b, 1);  // flag set to 1
     deriv d; deriv::deriv(&d, 1); // flag set to 1
     ...
 }
--

Steve Clamage, TauMetric Corp, steve@taumet.com