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]:
Unless an object is a bit-field or a base class subobject of zero size, the address of that object is the address of the first byte it occupies. Two objects a and b with overlapping lifetimes that are not bit-fields may have the same address if one is nested within the other, or if at least one is a base class subobject of zero size and they are of different types; otherwise, they have distinct addresses.
Are B
and C
different types? They both are an A
as well. Two distinct A
objects actually. A compiler writer is allowed to stop right there an allocate storage for B
and C
separately, without checking that A
is empty.
It's worth noting that with g++ the size is back to 1 if you have B
and C
inherit from separate bases:
#include<iostream>
class A {};
class A1 {};
class B : public A {};
class C : public A1 {};
class D : public B, public C {};
int main() {
std::cout << "Size of D is: " << sizeof(D) << std::endl;
return 0;
}