c++paddingvirtual-inheritancediamond-problemstruct-member-alignment

C++ Member and vtable order in diamond (multiple) virtual inheritance


I wanted to know the ordering of member variables and vtable pointers in C++ on a diamond virtual inheritance.

Consider the below inheritance:

class Base
{
    int b;
};

class Derived: public virtual Base
{
    int d;
};

class Derived2: public virtual Base
{
    int d2;
};

class Derived3: public Derived, public Derived2
{
    int d3;
};

I wanted to know the memory layout of class Derived3. I looked at following links online:

c++ data alignment /member order & inheritance

C++ Inheritance Memory Model

After going through the above links this is what I feel the memory layout of Derived3 could be:

void* vtable_ptr1 //vtable pointer of Derived
int d //Derived
void* vtable_ptr2 //vtable pointer of Derived2
int d2 //Derived2
int b //Base? not sure where will this be.
int d3 //Derived3

Online compilers give the size of Derived3 as 40 bytes, so I feel (assuming 8 bytes for pointer and 4 bytes for int) int b has to come after vtable_ptr2 (8(vtable_ptr1) + 4(d) + [4 padding] + 8(vtable_ptr2) + 4(d2) + 4(b) + 4(d3) + [4 class padding]) or before vtable_ptr1 (4(b) + [4 padding] + 8(vtable_ptr1) + 4(d) + [4 padding] + 8(vtable_ptr2) + 4(d2) + 4(d3)) so that padding comes into picture and increases the size of the class to 40.

To summarize, I have the following question:

Is the ordering correct? If not, what is the correct ordering of member variables and vtable pointers?


Solution

  • what is the correct ordering of member variables and vtable pointers?

    There is no "correct ordering". This is not specified in the C++ standard. Each compiler is free to arrange the memory layout of this class hierarchy in any fashion that's compliant with the C++ standard.

    A compiler may choose the layout of the class, in this situation, according to some fixed set of rules. Or, a compiler may try to optimize amongst several possibilities and pick a layout that can take advantage of hardware-related factors, like preferred alignment of objects, to try to minimize any required padding. This is entirely up to the compiler.

    Furthermore: if you review the text of the C++ standard you will not find even a single mention of anything called a "vtable". It's not there. This is just the most common implementation mechanism for virtual class methods and virtual inheritance. Instead of a pointer, it would be perfectly compliant with the C++ standard for a C++ compiler to use a two-byte index into a table, instead of an entire pointer -- into a table containing records that define each particular class's virtual properties. This would work perfectly fine as long as the number of all classes with virtual properties does not exceed 65536.

    In other words: you have no guarantees, whatsoever, what this class's layout will be, in memory, or what its size is. It is not specified in the C++ standard and is entirely implementation-defined.