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

Is the Empty Base Class Optimization now a mandatory optimization (at least for standard-layout classes)?

本文关键字:优化 于标准 标准 基类 布局      更新时间:2023-10-16

根据 C++119.1/7(草案 n3376),标准布局类是具有以下特征的类:

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

  • 没有虚函数(10.3)也没有虚拟基类(10.1),

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

  • 没有非标准布局基类,

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

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

因此,空类是标准布局类

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

此外,第9.2/19号文件指出:

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

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

是的,你是对的,这是在"重新审视 POD"提案中指出的:http://www.open-std.org/jtc1/sc22/WG21/docs/papers/2007/n2342.htm#ABI

Embarcadero编译器文档也指出:http://docwiki.embarcadero.com/RADStudio/en/Is_standard_layout

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

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

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

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