C++ 空基类优化现在是强制性优化吗(至少对于标准布局类)?

C++ 空基类优化现在是强制性优化吗(至少对于标准布局类)?,c++,c++11,language-lawyer,C++,C++11,Language Lawyer,根据C++11 9.1/7草案n3376,标准布局类是指: 没有此类类型或引用的非标准布局类或数组类型的非静态数据成员 没有虚拟函数10.3和虚拟基类10.1 对所有非静态数据成员具有相同的访问控制条款11 没有非标准布局基类 在最派生的类中没有非静态数据成员,并且最多有一个基类具有非静态数据成员,或者没有基类具有非静态数据成员,以及 没有与第一个非静态数据成员类型相同的基类 因此,空类是标准布局类;另一个以空类为基的类也是标准布局类,前提是该类的第一个非静态数据成员与基的类型不同 此外,第9.

根据C++11 9.1/7草案n3376,标准布局类是指:

没有此类类型或引用的非标准布局类或数组类型的非静态数据成员

没有虚拟函数10.3和虚拟基类10.1

对所有非静态数据成员具有相同的访问控制条款11

没有非标准布局基类

在最派生的类中没有非静态数据成员,并且最多有一个基类具有非静态数据成员,或者没有基类具有非静态数据成员,以及

没有与第一个非静态数据成员类型相同的基类

因此,空类是标准布局类;另一个以空类为基的类也是标准布局类,前提是该类的第一个非静态数据成员与基的类型不同

此外,第9.2/19号决议指出:

指向标准布局结构对象(使用reinterpret_cast进行适当转换)的指针指向其初始成员,或者如果该成员是位字段,则指向其所在的单元,反之亦然。[注:因此,标准布局结构对象中可能会有未命名的填充,但不会在其开头,这是实现适当对齐所必需的。-结束注]


这似乎意味着空基类优化现在是一种强制优化,至少对于标准布局类是如此。我的观点是,如果不强制执行空基优化,那么标准布局类的布局将不是标准的,而是取决于实现是否实现了所述优化。我的推理是正确的,还是我遗漏了什么?

是的,你是正确的,这一点在PODs重温提案中指出:

Embarcadero编译器文档还声明:

另一个关键点是[class.mem]/16

如果两个标准布局结构第9条类型具有相同数量的非静态数据成员,并且声明顺序中相应的非静态数据成员具有布局兼容类型3.9,则它们是布局兼容的

请注意,只有数据成员影响布局兼容性,而不是基类,因此这两个标准布局类是布局兼容的:

struct empty { };
struct stdlayout1 : empty { int i; };

struct stdlayout2 { int j; };

你的标题似乎有误导性——这是因为空基不会破坏标准布局,而你的问题似乎更多地是关于空基优化。@ildjarn:我的观点是,如果空基优化不是强制性的,那么,标准布局类的布局将不是标准的,而是取决于实现是否实现了优化。但9.2/19似乎要求这样的优化。如果你能建议一个更好的标题,我很乐意更改。你的推理似乎是正确的。把它作为你自己的答案贴出来;我认为,你的最后一段很好地总结了这一点,比如空基类优化现在是强制性的优化,至少对于标准布局类来说是这样吗?我认为你误解了本文。派生类的第一个成员基类是否为空。是否实际定义了初始序列?哪里这是怎么一回事?基本子对象是否保证排在成员之前?例如,如果我有结构A{char x[17];};结构B{char x[9];};,可能是结构Foo:A{int Foo;};和struct Bar:B{int Bar;}具有相同的初始序列,因为它们都以int开头?啊,没关系!要成为标准布局,您不能在基类和最派生的类中都有数据成员。问题解决了。