0

I read about VTT's structure from here(2.6.2). However, I do not understand the purpose of all the elements present.

The primary virtual pointer should point to the primary virtual table of D (in the vtable group, correct?)

The secondary VTTs contain VTTs that are given to the direct non-virtual base classes (let's call them B) when they are constructed. My understanding is that because these direct base classes (B) may inherit from virtual classes, these direct base classes (B) should give these already initialized virtual classes some other vtable, to "make them believe" they are only part of each B. Is this correct?

Now, what is the purpose of the last 2 types of entries: secondary virtual pointers and virtual VTTs? I understand that virtual classes in the inheritance hierarchy were not given a proper final vtable, so this could be one of the purpose. Also, virtual classes may inherit themselves from other virtual classes (consider that V1 inherits from V2). Then V2 needs again a special vtable to "make it believe" it is part of V1 (when V1 is being constructed).

I would appreciate it if you could explain the exact content and purpose of each type of entry in the VTT.

user42768
  • 1,951
  • 11
  • 22
  • Do you understand C++ multiple & virtual inheritance, order of base class initialization, and run-time behavior during the construction of a complex object? Given a type with multiple bases classes (which may or may not be virtual), some of which which declare or define a method `foo` (which may or may not be declared `virtual`), can you always predict which exact definition of `foo` is called when it's called from one of the constructors involved? Including calls from initializer lists? If you understand the complexity of the language, it becomes easier to understand an implementation. – MSalters Jun 09 '17 at 12:11
  • I believe I do. But I do not understand the wording of that explanation. Knowing the exact purpose of the last two elements (having an explicit scenario) would help. – user42768 Jun 09 '17 at 12:28
  • "_secondary VTTs_" There is no such thing, AFAIK – curiousguy Jun 24 '18 at 19:53

1 Answers1

0

Liskov Substituability means that a derived class must be usable wherever a base class would be acceptable. In C++, this means you can pass the address of a Derived object to a function that takes a Base*.

Now, during the construction of a complex object, you may have the situation that *this is such a Derived object per the C++ rules (as a Derived ctor has successfully run), and you must therefore be able to pass *this to a function expecting a Base*.

But with multiple and virtual inheritance, you need extra precautions. The Base* must point to a Base sub-object. And in the Itanium ABI, that base sub-object must have a vtable pointer that properly describes the behavior of the partially-constructed object. That behavior depends on exactly what parts are and aren't constructed.

While the object can be partially constructed, the granularity of this is just the class level. The most derived constructor called determines exactly which base class constructors will run (this is not dependent on run-time behavior). And each of these either has run, or hasn't.

Therefore, a viable implementation is to have a set of vtables, and a set of vtable pointers in each base class subobject (possibly overlapping), and to set the vtable pointers as each constructor successfully finishes.

Virtual base classes are not obviously related to virtual functions, but got their name from the fact that you can store virtual base class offsets in vtables. This offset is needed when you pass Derived* this to a function taking a Base*, where that Base type is a virtual base class of Derived. (You'd use a fixed offset when it's a regular base class, and that offset could even be zero)

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • I know this information, but I do not understand explicitly what the last two types of elements in the VTT are meant for. If I were to create an object, I would do it like this: find a topological sorting of the virtual bases. Create the virtual bases in this order (but for each virtual base V1 which is derived from V2, also virtual, I need to make V2 think it is part of a V1 object, when V1 is created). After finishing with virtual bases, I can move on to direct non-virtual bases. I instantiate them, giving them a secondary VTT (such that they can "fool" their virtual bases). – user42768 Jun 09 '17 at 13:07
  • What do I need the last two types in the VTT for in this scenario? – user42768 Jun 09 '17 at 13:07
  • @user42768: I might be missing something in your description, but where exactly do you propose to do such a sorting? Remember that the derived class may not be known to the base base class. In particular, a class may not even know it's going to be used as a virtual base class, and in fact this could vary between uses. A derived class may have two virtual base classes, and should be able to act as either. How do you expect that to work with just a single virtual table? – MSalters Jun 09 '17 at 13:12
  • In the "in-charge" constructor (or however it is called) of the derived class, this sorting should decide which virtual bases are created first. I know that we must have more virtual tables, this is not what I have trouble understanding. I do not know what the last two types mean. Do secondary virtual pointers actually point in the vtable group to the specific location of the specific class they refer to? Also, which exactly are these classes? And what are virtual VTTs used for? – user42768 Jun 09 '17 at 13:20
  • @user42768 "_giving them a secondary VTT_" is there even such thing as "secondary VTT"? – curiousguy Jun 24 '18 at 19:43
  • "_But with multiple and virtual inheritance, you need extra precautions_" What extra precautions are needed for virtual calls during construction in classes with multiple non virtual inheritance? – curiousguy Jun 24 '18 at 19:51