C++20 是否取消了类成员按升序排列的要求?

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]),两个成员都不是零大小的子对象,并且它们的类不是联合。