0

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?

Topper Harley
  • 375
  • 4
  • 17
  • 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 Nov 04 '18 at 23:10
  • @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 Nov 06 '18 at 19:39
  • @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: https://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 Nov 06 '18 at 20:52
  • @IgorTandetnik Wrong. How do you think code finds the vtable for a given object? Hint: vtable pointer aka vptr. – curiousguy Nov 06 '18 at 22:18
  • @IgorTandetnik Your example code isn't even remotely related to what I'm talking about as it doesn't compare **some non-pure virtual functions vs. only pure virtual functions** as mentioned in the above question. – curiousguy Nov 06 '18 at 22:26
  • @IgorTandetnik "_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_" Complete objects aren't even related with RTTI: RTTI is often **used to find the most derived object**, but only there is an odd C++ extension, RTTI doesn't find "complete objects" that is objects that aren't subobjects. **I think the complete object concept isn't relevant to the question.** – curiousguy Nov 06 '18 at 22:40
  • @IgorTandetnik "_Vtable - short for "virtual table" - has everything to do with virtual member functions_" You seem to be under the general belief that in C++ a class object needs a vtable pointer iff the class has at least virtual function. This isn't true in general: GCC uses a vtable pointer for any class whose definition needs the virtual keyword. – curiousguy Nov 06 '18 at 22:45
  • @curiousguy Indeed, I have no idea what you are talking about. First you said that "the need for vtable ... comes from the non do-nothing c/d-tor". You no longer seem to defend this proposition. There's apparently a function in MSVC implementation named, literally, `_RTTICompleteObjectLocator`; in that implementation, there's something called "complete object locator" that's clearly related to RTTI. – Igor Tandetnik Nov 06 '18 at 22:53
  • @IgorTandetnik The comment system is for short comments which is why I didn't include a quote for context when replying to your only comment, as I was expecting the reader to read my comment as a specific tailored reply. I regret now. Let me start over: – curiousguy Nov 06 '18 at 22:58
  • "_There can never be a complete object of an abstract class_" Only correct by language definition: you can't define a complete object which has an abstract class type. Not relevant in any way as **the issues of vtable and virtual functions relates to inheritance and not data member subobjects**. If a class is only ever used a member subobject (by virtue of programming policy, or forced by an imaginary compiler extension that makes a type impossible to use to declare a complete object, but still usable as a member), the need for vtable wouldn't change. – curiousguy Nov 06 '18 at 23:20
  • *I don't know the specifics of RTTI in MSVC* so let's discuss C++ implementations in general: specifically those that use vtables to handle virtual function calls (that's 100% of C++ implementations of course but I don't want to read the boring "the C++ std doesn't mandate vtables"). – curiousguy Nov 07 '18 at 00:00
  • "_It does not follow from the lack of one that abstract classes also lack virtual table._" Here you seem to say that some abstract classes need a vtable and some don't; then "_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_" (1) you seem to say that **abstract classes might need a vtable for the purpose of calling non-pure virtual functions** (Am I correctly interpreting?) – curiousguy Nov 07 '18 at 00:03
  • (2) and you seem to suggest that those **abstract classes that don't have non-pure virtual functions wouldn't need a vtable** (correct reading?). These were my assumptions while reading your comment. (If my reading was wrong, I would just remove my answer to your comment.) – curiousguy Nov 07 '18 at 00:05
  • @curiousguy No, I didn't say that. All abstract classes would generally have a vtable. A discussion of an abstract class that has both pure and non-pure virtual functions was just by way of illustration - it's a case were a vtable is obviously needed. The fact that the OP couldn't locate one is merely an artifact of their methodology (which relies on implementation details of MSVC RTTI, details that happen not to apply to abstract classes). Still not sure what constructors and destructors have to do with any of this, and why you would mention them. – Igor Tandetnik Nov 07 '18 at 00:18
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/183228/discussion-between-curiousguy-and-igor-tandetnik). – curiousguy Nov 07 '18 at 00:48
  • 1
    Intentionally omitting the v-table is common in the kind of code that uses interfaces heavily. https://learn.microsoft.com/en-us/cpp/cpp/novtable?view=vs-2017 – Hans Passant Nov 07 '18 at 00:53
  • VMT is the same thing as vtable? – curiousguy Nov 07 '18 at 01:18
  • @HansPassant I presume the compiler doesn't even need that special keyword for c/d-tors that doing nothing interesting. – curiousguy Nov 07 '18 at 01:26

1 Answers1

1

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).

curiousguy
  • 8,038
  • 2
  • 40
  • 58