I am trying to understand the object layout for C++ in multiple inheritance. For this purpose, I have two superclasses A, B and one subclass C. What I expected to see when trying dumping it was: vfptr | fields of A | vfptr | fields of B | fields of C.
I get this model but with some zeros that I don't understand. Here is the code I am trying
#include <iostream>
using namespace std;
class A{
public:
int a;
A(){ a = 5; }
virtual void foo(){ }
};
class B{
public:
int b;
B(){ b = 10; }
virtual void foo2(){ }
};
class C : public A, public B{
public:
int c;
C(){ c = 15; a = 20;}
virtual void foo2(){ cout << "Heeello!\n";}
};
int main()
{
C c;
int *ptr;
ptr = (int *)&c;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
ptr++;
cout << *ptr << endl;
return 0;
}
And here is the output I get:
4198384 //vfptr
0
20 // value of a
0
4198416 //vfptr
0
10 // value of b
15 // value of c
What is the meaning of the zeros in between? Thanks in advance!
That depends upon your compiler. With clang-500, I get:
I am sure there's a GDB way too, but this is what I get if I dump pointer-sized words with LLDB at the address of the class object:
This layout seems sensible, right? Just what you expect. The reason why that doesn't show as clean in your program as it does in the debugger is that you are dumping int-sized words. On a 64-bit system sizeof(int)==4 but sizeof(void*)==8
So, you see your pointers split into (int,int) pairs. On Linux, your pointers don't have any bit set beyond the low 32, on OSX my pointers do - hence the reason for the 0 vs. 1 disparity