标准布局c ++

jmi*_*hra 17 c++ pod standard-layout c++11

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

 A standard layout has no base classes of the same type as the first 
    non-static data member
Run Code Online (Sandbox Code Playgroud)

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

struct NonStandardLayout3 : StandardLayout1 {
    StandardLayout1 x; // first member cannot be of the same type as base
};
Run Code Online (Sandbox Code Playgroud)

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

struct StandardLayout5 : StandardLayout1 {
    int x;
    StandardLayout1 y; // can have members of base type if they're not the first   
};
Run Code Online (Sandbox Code Playgroud)

这是对此之上的修正.

CB *_*ley 16

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

但是,当基类与第一个数据成员具有相同类型时尝试执行此操作会违反C++内存模型,该模型要求相同类型的不同对象必须具有不同的地址.

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

如果一个是另一个的子对象,或者如果至少一个是零大小的基类子对象并且它们是不同类型的,则不是位字段的两个对象可以具有相同的地址; 否则,他们应有不同的地址

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

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

如果没有这种限制,以下类型(Type1Type2)将不可能与布局兼容(尽管它们将是标准布局类).

struct S1 {};
struct S2 {};

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

struct Type2 : S1 {
    S2 s;
    int m;
};
Run Code Online (Sandbox Code Playgroud)

  • 这正是§9/ 7中此规则的脚注所说的:"[此规则]确保具有相同类类型且属于同一最派生对象的两个子对象不在同一地址分配" (3认同)