Here is my cpp code.
#include <iostream>
using namespace std;
class A {
public:
int val;
char a;
};
class B: public A {
public:
char b;
};
class C: public B {
public:
char c;
};
int main()
{
cout << sizeof(A) << endl;
cout << sizeof(B) << endl;
cout << sizeof(C) << endl;
return 0;
}
The output of the program (in gcc) is:
8
12
12
This output confuses me a lot.
I know that the alignment may be the reason why sizeof(A) equals to 8. (sizeof(int) + sizeof(char) + 3 bytes padding
)
And I also guess that the expansion of sizeof(B) (sizeof(B) == sizeof(A) + sizeof(char) + 3 bytes padding
) is to avoid overlap when copy occurs. (is that right?)
But what I really don't know why sizeof(B) is equal to sizeof(C).
Thanks a lot.
Both GCC and Clang follow the Itanium C++ ABI document, which specifies:
... implementations may freely allocate objects in the tail padding of any class which would not have been POD in C++98
class A
is POD, so the compiler cannot put stuff into its padding. class B
isn't POD, so the compiler is free to re-use the padding within the base class layout for members of derived objects. The basic idea here was that the C++ class layout should mirror the equivalent C struct layout for POD types, but there is no limitation for other classes. Because the meaning of "POD" has changed multiple times, they explicitly use the definition from C++98.
EDIT: About the rationale. POD-types are very simple classes that could be implemented as struct
in C. For those types the layout should be identical to the layout a C compiler would create. In particular they want to allow C-tools like memcpy
for A
. If char b;
were within the padding of A
, memcpy
would destroy it.
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