以下所有操作均将在GCC 9.1上使用x86-64中的Compiler Explorer在上完成-O3。
我有以下代码:
struct Base {
Base() {}
double foo;
int bar;
};
struct Derived : public Base {
int baz;
};
int main(int argc, char** argv)
{
return sizeof(Derived);
}
Run Code Online (Sandbox Code Playgroud)
16如我所料,它正确地返回的8个字节foo,的4个字节bar和的4个字节baz。这仅是因为Derived继承自Base,因此bar由于Derived是同时包含Base和Derived元素的单一类型而不必填充。
我有两个问题,如下所示:
第一个问题
如果我删除的显式构造函数Base() {},它将开始返回24,而不是16。也就是说,它在bar和之后添加了填充baz。
我无法解释为什么拥有显式默认构造函数与具有隐式默认构造函数有什么不同。
第二个问题
如果然后我更改struct为classfor Base …
让我们考虑结构:
struct S1 {
int a;
char b;
};
struct S2 {
struct S1 s; /* struct needed to make this compile as C without typedef */
char c;
};
// For the C++ fans
struct S3 : S1 {
char c;
};
Run Code Online (Sandbox Code Playgroud)
S1的大小为8,由于对齐而预期.但是S2和S3的大小是12.这意味着编译器将它们构造为:
| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10| 11|
| a | b | padding | c | padding |
Run Code Online (Sandbox Code Playgroud)
编译器可以在不破坏对齐约束的情况下将c放在6 7 …