将默认构造函数添加到基 class 将 sizeof() 更改为派生类型
Adding a default constructor to a base class changes sizeof() a derived type
我倾向于认为我对 C++ 内部结构和内存布局有很好的掌握,但这个让我感到困惑。我有以下测试代码:
#include <stdio.h>
struct Foo
{
//Foo() {}
int x;
char y;
};
struct Bar : public Foo
{
char z[3];
};
int main()
{
printf( "Foo: %u Bar: %u\n", (unsigned)sizeof( Foo ), (unsigned)sizeof( Bar ) );
}
输出合理:
Foo: 8 Bar: 12
但是,这是非常奇怪的部分,如果我取消注释 Foo() 上的简单默认构造函数,sizeof(Bar) 会发生变化!添加一个构造函数怎么可能改变这些类的内存布局?
Foo: 8 Bar: 8
使用 gcc-7.2 编译
GCC 遵循 C++ 的 Itanium ABI,这可以防止 POD 的尾部填充用于存储派生的 class 数据成员。
添加用户提供的构造函数意味着 Foo
不再是 POD,因此该限制不适用于 Bar
。
See this question 有关 ABI 的更多详细信息。
我倾向于认为我对 C++ 内部结构和内存布局有很好的掌握,但这个让我感到困惑。我有以下测试代码:
#include <stdio.h>
struct Foo
{
//Foo() {}
int x;
char y;
};
struct Bar : public Foo
{
char z[3];
};
int main()
{
printf( "Foo: %u Bar: %u\n", (unsigned)sizeof( Foo ), (unsigned)sizeof( Bar ) );
}
输出合理:
Foo: 8 Bar: 12
但是,这是非常奇怪的部分,如果我取消注释 Foo() 上的简单默认构造函数,sizeof(Bar) 会发生变化!添加一个构造函数怎么可能改变这些类的内存布局?
Foo: 8 Bar: 8
使用 gcc-7.2 编译
GCC 遵循 C++ 的 Itanium ABI,这可以防止 POD 的尾部填充用于存储派生的 class 数据成员。
添加用户提供的构造函数意味着 Foo
不再是 POD,因此该限制不适用于 Bar
。
See this question 有关 ABI 的更多详细信息。