How virtual inheritance is implemented in memory by c++ compiler?

c++, c++11, visual-c++

Solution

This pdf contains everything that you need to understand about, how virtual inheritance is implemented in VC++, by the writer of the compiler.

Below is the disassembly for the constructor of `class three`,

00A516BD  cmp         dword ptr [ebp+8],0 
00A516C1  je          three::three+60h (0A516F0h) 
00A516C3  mov         eax,dword ptr [this] 
00A516C6  mov         dword ptr [eax],offset three::`vbtable' (0A57828h) => 4 Bytes
00A516CC  mov         ecx,dword ptr [this] 
00A516CF  add         ecx,8 
00A516D2  call        one::one (0A51253h) 
00A516D7  or          dword ptr [ebp-0D4h],1 
00A516DE  mov         ecx,dword ptr [this] 
00A516E1  add         ecx,10h 
00A516E4  call        two::two (0A512BCh) 
00A516E9  or          dword ptr [ebp-0D4h],2 
00A516F0  mov         eax,dword ptr [this] 
00A516F3  mov         ecx,dword ptr [eax] 
00A516F5  mov         edx,dword ptr [ecx+4] 
00A516F8  mov         eax,dword ptr [this] 
00A516FB  mov         dword ptr [eax+edx],offset three::`vftable' (0A57820h)  => 4 Bytes
00A51702  mov         eax,dword ptr [this] 
00A51705  mov         ecx,dword ptr [eax] 
00A51707  mov         edx,dword ptr [ecx+8] 
00A5170A  mov         eax,dword ptr [this] 
00A5170D  mov         dword ptr [eax+edx],offset three::`vftable' (0A57814h)   => 4 Bytes
00A51714  mov         eax,dword ptr [this] 
00A51717  pop         edi  
00A51718  pop         esi  
00A51719  pop         ebx  
00A5171A  add         esp,0D8h 

As you can see above, The virtual base table pointer takes 4 bytes, (vbtable) 2 virtual function table pointer takes 4 * 2 = 8 bytes, (vftable) The member `one::_a` takes 4 bytes The member `two::_a` takes 4 bytes

Hence in all 20 bytes. The reason for 2 virtual function table pointers is given in the pdf (page 17) as follows,

"In Visual C++, to avoid costly conversions to the virtual base P when fetching a vftable entry, new virtual functions of T, receive entries in a new vftable, requiring a new vfptr, introduced at the top of T."

Problem

I am baffled by the VIRTUAL keyword. I am trying to find how does compiler implement this in memory. ok so let me explain with examples. I am using Microsoft Visual studio 2010 as implementation of virtual depends on compiler. here is the first code ``` #include<iostream> class one { int _a; public: virtual ~one(){} }; class two:public one { int _a; public: virtual ~two(){} }; int main() { using namespace std; cout<<"sizeof two="<<sizeof(two)<<endl; return 0; } ``` o/p is 12 bytes, because of _vptr_two,one::_a and two::_a here is another example code ``` #include<iostream> class one { int _a; public: virtual ~one(){} }; class two { int _a; public: virtual ~two(){} }; class three:virtual public one,virtual public two { }; int main() { using namespace std; cout<<"sizeof three="<<sizeof(three)<<endl; return 0; } ``` in this case o/p is 20 bytes :O, how come?? Please explain!! According to me it should be 16 bytes. __vptr_three(pointer to vtable), _vptr1_three(pointer to virtual base class table), one::_a and two::_a. And why virtual base class table is maintained ?

Original source