45

在 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;

根据上述标准文本,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 已经变成了一个注释。但是,注释在 ISO 标准中是非规范性的(意味着编译器供应商可以忽略它们)。而且我找不到任何其他可能适用的文本。

我的问题是: C++20 是否仍然在某个地方指定(规范地)保证&a.y < &a.z和/或&f.p < &f.r?或者编译器现在是否有权在所有情况下重新排序类成员,除了标准布局类的第一个子对象?

假设 N4860 和已发布的标准之间没有进一步的变化,我猜。

4

1 回答 1

30

这仍然由[expr.rel]/(4.2)保证,描述了内置<, <=, >, 和>=指针值表达式的行为。

如果两个指针指向同一个对象的不同非静态数据成员,或者这些成员的子对象,递归地,如果两个成员具有相同的访问控制([class. access]),这两个成员都不是大小为零的子对象,并且它们的类不是联合。

于 2020-05-04T11:11:21.110 回答