这是我的cpp代码。
#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;
}
程序的输出(在gcc中)是:
8
12
12
这个输出让我很困惑。
我知道对齐可能是sizeof(A)等于8的原因。(sizeof(int) + sizeof(char) + 3 bytes padding
)
我还猜测sizeof(B)(sizeof(B) == sizeof(A) + sizeof(char) + 3 bytes padding
)的扩展是为了避免重置发生时的重叠。 (是吗?)
但我真的不知道为什么sizeof(B)等于sizeof(C)。
非常感谢。
答案 0 :(得分:13)
GCC和Clang都遵循Itanium C++ ABI文件,该文件指定:
...实现可以在任何类的尾部填充中自由分配对象,这些对象在C ++ 98中不是POD
class A
是POD,因此编译器无法将内容放入其填充中。 class B
不是POD,因此编译器可以自由地在基类布局中重用派生对象成员的填充。这里的基本思想是C ++类布局应该镜像POD类型的等效C结构布局,但是对其他类没有限制。由于“POD”的含义已多次更改,因此它们明确使用了C ++ 98中的定义。
编辑:关于理由。 POD类型是非常简单的类,可以在C中实现为struct
。对于这些类型,布局应该与C编译器创建的布局相同。特别是他们希望允许memcpy
之类的C工具用于A
。如果char b;
位于A
的填充范围内,则memcpy
会将其销毁。