Object-oriented – Avoiding vtable pointers in objects in C++

cinterfacesmultiple-inheritanceobject-oriented

In my previous question, it was highlight that implementations of C++ such as GCC must store a vtable pointer in every copy of a class for each parent class which has a virtual function.

So a class which implements say 5 "interfaces" (i.e. pure abstract classes) must be at least 5 pointers in size before even it's own members are added.

At first glance, this seems necessary. When we upcast, all we can do is change the pointer. But we need a new vtable for that upcasted pointer. So there's not much option other than putting it in the object itself.

The downside of this is that we pay a per-object cost for virtual parent classes, even ones with no members.

How about instead, making a pointer "two pointers". The first pointer is a pointer to the object. The second is a pointer to it's vtable. This could perhaps only be done for virtual objects.

The object itself could now just be pure data, no need for vtable pointers.

Note then we only need one vtable pointer, even if there's multiple parents. The vtable itself could have entries describing how to upcast, or perhaps the compiler just knows how to do this.

Is there any reason this approach is not viable> Are there any C++ implementations that do this?

(Note: I understand one can avoid pure abstract bases as interfaces and "duck typing" and in the future concepts but lets ignore that for the moment)

Best Answer

How about instead, making a pointer "two pointers".

This would bloat every pointer, even those which don't use dynamic polymorphism. Remember: you have to be able to cast any object pointer to void* and back to that type with valid behavior. That wouldn't be possible unless every pointer used your "two pointer" approach. Plus, the C++ standard does not permit the size of an object pointer to be determined by what type it points to.

This would also break ABI with C and every C API function ever written. C++ implementations like to be able to call C APIs.

C++ is a language that prefers to follow the "don't pay for what you don't use" rule. Users who use lots of multiple inheritance of virtual interfaces pay for it; users who don't use these things don't have to pay anything. That is as it should be.