0
votes

I am learning about virtual function tables and their representation by analyzing a binary of a simple program written in Visual C++ (with some optimizations on).

A few days ago I asked this question while being stuck on virtual method table content with identical COMDAT folding on.

Now I'm stuck on something else: whenever I analyze a class, I need to find its Virtual Method Table. I can do this by finding either its RTTITypeDescriptor or _s_RTTIClassHierarchyDescriptor, finding a cross reference on it, which should lead me to the _RTTICompleteObjectLocator. When I find a cross reference to the Complete Object Locator, it is written just before the VMT (basically -1st entry of the VMT).

This approach works on some classes (their names start with C in my program). Then there are classes, that are named with I in the beginning and I am able to pair them with other classes starting with C -- for example there is class CClass and it inherits from IClass. These I-classes are probably serving as interfaces to the C-classes and thus they probably only contain abstract methods.

By searching a cross reference to Type Descriptor or Class Hierarchy Descriptor of any of the I-classes I cannot find anything -- there is no Complete Object Locator that would lead me to the VMT of the class (that should be full of references to pure_virtual call if I am correct about the all-abstract methods in the I-classes and if I understand correctly what VMT of abstract class looks like).

Why do the I-classes have no VMT? Did the compiler optimize it out because it would just be full of references to pure_virtual call and manages it in a different way?

1
There can never be a complete object of an abstract class, so I suppose there's no need to locate one; hence the lack of Complete Object Locator. It does not follow from the lack of one that abstract classes also lack virtual table. For one thing, a class is abstract as soon as it has at least one pure virtual member function; it could also very well have normal, non-pure virtual ones.Igor Tandetnik
@IgorTandetnik The need of the vtable has nothing to do with having non-pure virtual functions. It comes from the non do-nothing c/d-tor.curiousguy
@curiousguy Nonsene. Vtable - short for "virtual table" - has everything to do with virtual member functions and nothing whatsoever to do with constructors or destructors (except to the extent that destructors may be virtual). Consider: rextester.com/XSAL86320 . There are two classes, identical in all respects except that one has a virtual member function and the other doesn't; both have non-trivial constructor and destructor. The one with a virtual function is larger; I posit that the extra space is occupied by the vtable pointer.Igor Tandetnik
@IgorTandetnik Wrong. How do you think code finds the vtable for a given object? Hint: vtable pointer aka vptr.curiousguy
Intentionally omitting the v-table is common in the kind of code that uses interfaces heavily. docs.microsoft.com/en-us/cpp/cpp/novtable?view=vs-2017Hans Passant

1 Answers

1
votes

These "interfaces" abstract classes probably have need no user written code in any their constructors and destructors (these either have an empty body and no ctor-init-list, or simply are never user defined); let's call these pure interface classes.

[Pure interface class: concept related but not identical to Java interfaces that are (were?) defined as having zero implementation code, in any member function. But be careful with analogies, as Java interfaces inheritance semantic isn't the same as C++ abstract classes inheritance semantic.]

It means that in practice no used object ever has pure interface class type: no expression ever refers to an object with pure interface type. Hence, no vtable is ever needed, so the vtable, which may have been generated during compilation, isn't included in linked code (the linker can see the symbol of the pure interface class vtable isn't used).