What I know is that size of empty class is 1 just to conform to the standard that does not allow objects (and classes thereof) of size to be 0. Here, I am getting size of a derived class D as 2. Why behavior is different in this case given that there is no data member or virtual pointer inherited from class B and C to D?
#include<iostream>
using namespace std;
class A {};
class B : public A {};
class C : public A {};
class D : public B, public C {};
int main() {
cout<<"Size of D is: "<<sizeof(D)<<endl;
return 0;
}
To me it seems that whether or not the empty base optimization can be applied here, depends on how one interprets [intro.object/8]:
Are
B
andC
different types? They both are anA
as well. Two distinctA
objects actually. A compiler writer is allowed to stop right there an allocate storage forB
andC
separately, without checking thatA
is empty.It's worth noting that with g++ the size is back to 1 if you have
B
andC
inherit from separate bases:Live Example
This is because you are inheriting from two base classes that have themselves been derived from the same base class
A
, see how the output changes when you change your program to thisAs you see now the size of
D
is1
The problem is similar to that of the dreaded diamond that you probably know about. The compiler is trying to disambiguate the two instances of
A
present inD
in your example. And the empty base optimization is not applied here, the standard does not require it and the compiler does not implement it (see below)The standard explicitly allows compilers to not apply the empty base optimization for multiple inheritance cases. Relevant quote from the standard here