Construction vtables
Martin von Loewis
loewis at informatik.hu-berlin.de
Thu Mar 2 16:33:00 UTC 2000
I just read the construction vtable passage, and I have some problems
understanding it.
First, the condition under which a class 'has' a VTT is
confusing. What exactly means condition 2), why is this alternative to
condition 1)? In particular, what does 'overridden along a virtual
path' mean? And how could condition 2 be true while condition 1 is
false?
I interpret this as saying: '... has a virtual function in a virtual
base class, which is overridden in a derived class'. So apparently the
class has to have a virtual base, which implies that condition 1 is
already true.
Also, where does the virtual function have to be overridden? In the
complete object, or in the class of the VTT? I'd assume the latter.
IOW, I think this needs to be phrased as
1. indirect or direct virtual base classes, and
2. one of the virtual bases is polymorphic (i.e. has virtual
functions), and
3. one of the virtual functions is overridden in the class being
considered crossing a virtual boundary.
It may be possible to relax the conditions (e.g. for gcc, I only
considered 1. and 2.), however, this seems to be the condition that
requires VTT creation in the fewest cases.
Next, the ordering of entries in the individual subobject vtables
seems to be duplicated incorrectly from the normal vtable layout. The
document says, in the VTT section, that vbase offsets come first,
followed by vcall offsets. In "Virtual Table Order", the document says
the contrary. I suggest that the ordering of things in the
construction vtable is the same as in the vtable of a complete object,
and that this is documented by reference, not by duplication.
Finally, it is not clear whose responsibility to provide the VTT
pointer in the most derived object. It appears as if this is the
caller's responsibility. However, it is not clear how this works in
the case of virtual destructors (where the caller may not be aware of
the need for a destruction vtable).
There are two alternative resolutions:
a) the destructor has two entry points, one without destruction vtable
and one with. If none is provided, the destructor uses the VTT of
its type, and invokes the dtor with VTT
b) the destructor always takes two arguments, and the caller may fill
in a value of zero - indicating that this is the most derived type.
The same approach could apply to constructors: a value of zero would
indicate, again, that the constructor has to fetch its VTT itself.
Regards,
Martin
More information about the cxx-abi-dev
mailing list