【问题标题】:Is the Empty Base Class Optimization now a mandatory optimization (at least for standard-layout classes)?空基类优化现在是强制优化吗(至少对于标准布局类)?
【发布时间】:2012-06-03 01:36:45
【问题描述】:

根据 C++11 9.1/7 (draft n3376)standard-layout 类是: p>

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

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

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

  • 没有非标准布局的基类,

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

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

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

此外,9.2/19 声明:

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

这似乎暗示 空基类优化 现在是强制优化,至少对于 standard-layout 类是这样。我的观点是,如果空基优化不是强制性的,那么 standard-layout 类的布局将不是标准的,而是取决于实现是否实现了所述优化。我的推理是否正确,还是我遗漏了什么?

【问题讨论】:

  • 您的标题似乎具有误导性——空基不会破坏标准布局,而您的问题似乎更多是关于空基优化。
  • @ildjarn:我的观点是,如果空基优化不是强制性的,那么 standard-layout 类的布局将不是标准的,而是取决于是否实现是否实现优化。但是 9.2/19 似乎要求进行这种优化。如果你能建议一个更好的标题,我很乐意改变它。
  • 你的推理似乎是正确的。将其发布为您自己的答案。 ;)
  • 我认为你的最后一段总结得很好——比如“空基类优化现在是强制优化吗,至少对于标准布局类来说是这样吗?”
  • 我认为您误解了文本。派生类的第一个成员是基类(是否为空)。

标签: c++ c++11 language-lawyer


【解决方案1】:

是的,你是对的,在“重新审视 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; };

【讨论】:

  • “初始序列”真的定义了吗?在哪里?它是什么?基础子对象是否真的保证在成员之前出现?
  • 即如果我有struct A { char x[17]; }; struct B { char x[9]; };,会不会是struct Foo : A { int foo; };struct Bar : B { int bar; } 具有相同的初始序列,因为它们都以int 开头?
  • 啊,没关系!要成为标准布局,您不能在基类和最派生类中都有数据成员。问题解决了。
猜你喜欢
  • 1970-01-01
  • 2010-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-16
相关资源
最近更新 更多