【问题标题】:Standard Layout c++标准布局 c++
【发布时间】:2012-07-03 06:24:07
【问题描述】:

我正在阅读C++ POD, Trivial and Standard Layout classes 上的精彩文章 关于标准布局,我还没有清楚了解的一个属性如下:-

 A standard layout has no base classes of the same type as the first 
    non-static data member

因此以下将不是标准布局,因为它的第一个成员与基类相同

struct NonStandardLayout3 : StandardLayout1 {
    StandardLayout1 x; // first member cannot be of the same type as base
};

但是在性能方面和属性方面,上述结构有何不同

struct StandardLayout5 : StandardLayout1 {
    int x;
    StandardLayout1 y; // can have members of base type if they're not the first   
};

这是对上面那个的更正。

【问题讨论】:

标签: c++ c++11 standard-layout


【解决方案1】:

原因是标准布局类型有效地要求“空基类优化”,其中没有数据成员的基类不占用空间,并且与派生类的第一个数据成员(如果有)具有相同的地址。

但是,当基类与第一个数据成员具有相同类型时尝试这样做违反了 C++ 内存模型,该模型要求相同类型的不同对象必须具有不同的地址。

来自 ISO/IEC 14882:2011 1.8 [intro.object]/6:

如果一个对象是另一个对象的子对象,或者如果至少一个是大小为零的基类子对象并且它们属于不同类型,则两个不是位域的对象可能具有相同的地址;否则,它们将具有不同的地址

有效地强制空基类,9.2 [class.mem] /20:

指向标准布局结构对象的指针,使用reinterpret_cast 适当转换,指向其 初始成员(或者如果该成员是位域,则指向它所在的单元),反之亦然。

如果没有此限制,以下类型(Type1Type2)就不可能是布局兼容的(尽管它们将是标准布局类)。

struct S1 {};
struct S2 {};

struct Type1 : S1 {
    S1 s;
    int k;
};

struct Type2 : S1 {
    S2 s;
    int m;
};

【讨论】:

  • 这正是第 9/7 节中此规则的脚注所说的:“[此规则] 确保具有相同类类型且属于同一最派生对象的两个子对象是不在同一个地址分配”
  • Type2 是根据 C++14 的 standard-layout 类,并且根据 N4606 和继续是 standard-layoutC++1z,因为S1S2 的类型不同。
  • 通过“如果没有此限制,以下类型(Type1 和 Type2)不可能是布局兼容的(尽管它们将是标准布局类)。”你的意思是说,根据标准,Type1 和 Type2 将是布局兼容的(因为它们是标准布局类),但实际上不可能这样实现它们(由于你帖子中的第一个引用:[ intro.object]/6)?谢谢。
  • 我一直在阅读您的最后一段,即我在之前的评论中引用的那段,以确保我理解正确。通过“无此限制”,您指的是“9.2 [class.mem] /20”,该限制要求标准布局对象必须与其第一个成员具有相同的地址,对吗?这种限制与“1.8 [intro.object]/6”相结合,使得第一个成员具有类型 U 且其基类也具有类型 U 的类型 T 不可能成为标准布局类型。 [继续]
  • @CharlesBailey 所以你的最后一段声明“没有这个限制”(“9.2 [class.mem] /20”),Type1 和 Type2 不能是布局兼容的。如果没有“9.2 [class.mem] /20”,Type1 和 Type2 将是标准布局类型,根据标准中的其余定义,它们将是布局兼容的。但是,即使标准规定它们是布局兼容的,也无法实现它们是布局兼容的,因为它们没有相同的内存布局。这是你的意思吗?谢谢你,我为坚持道歉。
猜你喜欢
  • 1970-01-01
  • 2013-04-06
  • 2017-02-15
  • 2012-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-19
相关资源
最近更新 更多