Search code examples
c++standardsmemory-layoutvptr

Storage layout of polymorphic objects according to C++ standard


I know that if a class contains any virtual functions, most compilers (if not all) add a vptr pointer to its objects. Some add it as the first element, some as the last. But does the C++ standard mandate usage of vptr and vtable? Could any compiler, theoretically, implement it any other way? If so, what are the guarantees regarding polymorphic objects' storage layout and overall size (e.g. are all the explicitly defined fields (+ padding) in a continuous memory block)?

I don't know if this differs between various C++ standards, that's why I only added the general C++ tag.


Solution

  • There's nothing in the C++ standard that mandates a particular implementation of virtual inheritance. The semantics of virtual inheritance are specified in terms of the appropriate syntax, and the expected results. C++ implementations are free to use any technical implementation that produces those results.

    For example, let's start with virtual inheritance of entire base classes:

    [class.mi]

    A base class specifier that contains the keyword virtual specifies a virtual base class. ... For each distinct base class that is specified virtual, the most derived object shall contain a single base class subobject of that type.

    The standard defines the syntax virtual as introducing virtual inheritance of the base class, and the expected result: that the most derived object contains a single instance of the virtually inherited base class. Full stop. End of story. How a particular implementation goes about doing that, is outside the scope of the standard.

    Similarly, for individual virtual functions:

    [class.virtual]

    If a virtual member function vf is declared in a class Base and in a class Derived, derived directly or indirectly from Base ... [ a few more requirements ] ... then Derived::vf ... overrides Base::vf.

    Some technical requirements omitted. The standard merely specifies that a virtual function in the derived class "overrides" the (same) function in the base class. How a particular C++ implementation goes about doing it, is not specified anywhere.