M.M*_*M.M 45 c++ class language-lawyer standard-layout c++20
在 C++17 中有规范文本 [class.mem]/17:
分配具有相同访问控制(第 14 条)的(非联合)类的非静态数据成员,以便后面的成员在类对象中具有更高的地址。具有不同访问控制的非静态数据成员的分配顺序未指定。
还有 [class.mem]/24:
如果标准布局类对象具有任何非静态数据成员,则其地址与其第一个非静态数据成员的地址相同
这里有两个例子:
struct A { int x, y, z; } a;
struct F { public: int p; private: int q; public: int r; } f;
Run Code Online (Sandbox Code Playgroud)
根据上述标准文本,C++17 保证&a.x < &a.y、&a.y < &a.z、 和&f.p < &f.r (但不保证&f.p < &f.q,因为F不是标准布局,所以 class.mem/24 不适用)。
但是,在 C++20 最终工作草案 N4860 中,根据CWG 2404进行了更改。[class.mem]/17 已经变成了 Note。然而,注释在 ISO 标准中是非规范的(意味着编译器供应商可以忽略它们)。我找不到任何其他可能适用的文本。
我的问题是: C++20 是否仍然在某处指定(规范地)保证&a.y < &a.z和/或&f.p < &f.r?或者编译器现在是否有权在所有情况下重新排序类成员,标准布局类的第一个子对象除外?
假设 N4860 和已发布的标准之间没有进一步的变化,我猜。
asc*_*ler 30
这仍然是通过保证[expr.rel] /(4.2) ,描述的行为内置<,<=,>,和>=对指针值的表达式。
如果两个指针指向同一对象的不同非静态数据成员,或递归地指向此类成员的子对象,则需要指向后声明成员的指针进行比较,前提是这两个成员具有相同的访问控制([class. access]),两个成员都不是零大小的子对象,并且它们的类不是联合。