This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Re: Why don't we just FIX the damn vthunk problem?


>>>>> Martin v Loewis <martin@mira.isdn.cs.tu-berlin.de> writes:

 >> Not necessarily.  We could set up the [cd]tor vtables in the code
 >> controlled by the in_chrg parameter, where we actually run the vbase
 >> [cd]tors.  Then the vbase ctors themselves would wait to set their own
 >> vtables until the end of the function.

 > I'm not sure I understand this approach. Consider

 > struct A{virtual void foo();};

 > struct B:virtual A{void foo();};

 > struct C:public B{
 >   int dummy;
 >   void foo();
 > };

 > When constructing a C instance, the B base constructor needs a vtable
 > that is only used inside B::B, and only when constructing C instances.
 > So if you want to statically allocate it, how does B::B know which
 > table to use, unless C::C passes it as a parameter?

Simply, because C::C does pass it, just in the B vptr slot rather than as a
normal parameter.

In this case, the B constructor vtable is just the B vtable, because B is
not a vbase.  The question is what to do with the A subobject vtable.
During B::B, we need an A vtable that reflects the B virtuals and the C
offsets.  To handle that, we could just set the vtable appropriately from
C::C before calling B::B, and again afterwards.

But when we add another level of inheritance, things get more complicated.

   struct D: public C {
     int dummy2;
     void foo ();
   };

Here, D::D has to communicate alternate vtables to both B::B and C::C.  To
support that, they have to set the A vptr for themselves, so we have to
pass the vtables up.  We can pass them separately or in an array; an array
is more compact.  So we have one pointer to pass around, and conveniently
there is a place in the object that we know will be unset until B::B is
run: namely, the B vptr (which is shared by C and D).  So we stick a
pointer to the array in B::vptr, and the B and C (and D) constructors look
there for it and pull it out before calling their base ctors.  B::B uses
the first element of the array, C the second, D the third and so on.

This is what EDG does.

Jason


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]