据我了解,当我的类型派生自没有数据成员或虚函数的基类时,空基类优化(EBO)应该会生效。在GCC和Clang下,这不会发生。这是一个示例:
struct EmptyClass { };
struct SmallerClass : public EmptyClass {
long long int _x[2];
};
struct BiggerClass : public EmptyClass {
SmallerClass _sc;
};
struct BiggestClass : public EmptyClass {
BiggerClass _bc;
SmallerClass _sc;
};
我完全希望BiggestClass
的大小等于4个long long int
的大小(32),但我在调试器中注意到它实际上是48。检查Clang中的AST( clang++ -cc1 -std=c++14 -fdump-record-layouts
和GCC(g++ -std=c++14 -fdump-lang-all -c
)都向我表明EmptyClass
在包含它的类的每一个中占了空间(BiggestClass
,它会出现两次)。
这是Clang AST输出:
*** Dumping AST Record Layout
0 | struct EmptyClass (empty)
| [sizeof=1, dsize=1, align=1,
| nvsize=1, nvalign=1]
*** Dumping AST Record Layout
0 | struct SmallerClass
0 | struct EmptyClass (base) (empty)
0 | long long [2] _x
| [sizeof=16, dsize=16, align=8,
| nvsize=16, nvalign=8]
*** Dumping AST Record Layout
0 | struct BiggerClass
0 | struct EmptyClass (base) (empty)
8 | struct SmallerClass _sc
8 | struct EmptyClass (base) (empty)
8 | long long [2] _x
| [sizeof=24, dsize=24, align=8,
| nvsize=24, nvalign=8]
*** Dumping AST Record Layout
0 | struct BiggestClass
0 | struct EmptyClass (base) (empty)
8 | struct BiggerClass _bc
8 | struct EmptyClass (base) (empty)
16 | struct SmallerClass _sc
16 | struct EmptyClass (base) (empty)
16 | long long [2] _x
32 | struct SmallerClass _sc
32 | struct EmptyClass (base) (empty)
32 | long long [2] _x
| [sizeof=48, dsize=48, align=8,
| nvsize=48, nvalign=8]
因此,看来BiggestClass
不仅比我预期的要大,而且BiggerClass
的尺寸也受到了欢迎。看起来,嵌套类会消除优化。
取消优化的背后原因是什么,有没有办法让我用一个普通的(空的)祖先来组合这些类型?