I think sizeof(Base)
should be 12. Why is it 16?
Without the virtual function, I get 4 and 8.
class Base{
public:
int i;
virtual void Print(){cout<<"Base Print";}
};
class Derived:public Base{
public:
int n;
virtual void Print(){cout<<"Derived Print";}
};
int main(){
Derived d;
cout<<sizeof(Base)<<","<<sizeof(d);
return 0;
}
expected result:12,16
actual result:16,16
why sizeof(Base) is not different of sizeof(Derived)
Because of the alignment introduced by the compiler.
That is architecture-dependent, but for sake of simplicity, I am going to assume we are referring a 64-bit architecture.
Scenario 64 bit / Clang 8.0.
The alignment of the type Base
is 8
bytes:
alignOfBase(): # @alignOfBase()
mov eax, 8
ret
The layout of Base
is composed by the variable member (int
) and the virtual table (vtptr
).
If we assume a "common" architecture where:
int
is 4 bytes size.vtptr
is a pointer. On a 64 bit architecture is 8 bytes size.We should have a sum of 4 + 8 = 12
, as you expect.
However, we need to remember the alignment of Base
is 8 bytes
. Therefore consecutive Base
types should be stored in location multiple of 8.
In order to guarantee that, the compiler introduces padding for Base
. That's why Base
is 16 bytes size.
For example, if we consider 2 consecutive Base
(base0
and base1
) without padding:
0: vtptr (base 0) + 8
8: int (base 0) + 4
12: vtptr (base 1) + 8 <--- Wrong! The address 12 is not multiple of 8.
20: int (base 1) + 4
With padding:
0: vtptr (base 0) + 8
8: int (base 0) + 4+4 (4 padding)
16: vtptr (base 1) +8 <--- Fine! The adress 16 is multiple of 8.
24: int (base 1) +4+4 (4 padding)
The same story is for Derived
type.
The layout of Derived
should be: vtptr + int + int
, that is, 8 + 4 + 4 = 16
.
The alignment of Derived
is 8
too:
alignOfDerived(): # @alignOfDerived()
mov eax, 8
ret
Indeed, in this case, there is no need to introduce padding in order to keep the Derived
aligned with the memory. The layout size will be the same as the real size.
0: vtptr (Derived 0)
8: int (Derived 0)
12: int (Derived 0)
16: vtptr (Derived 1) <---- Fine. 16 is multiple of 8.
24: int (Derived 1)
28: int (Derived 1)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With