类 /结构的成员的地址订购

发布于 2025-01-29 04:20:15 字数 100 浏览 1 评论 0原文

C ++ 23草案规定,后来的结构或类的非静态数据成员必须具有更高的地址。 AFAIK较早的标准也需要部分,但是有一些规则,允许编译器重新排序这些数据成员时。谁能告诉我哪些规则完全适用?

The C++23 draft mandates that later non-static data members of a structure or class must have higher addresses. AFAIK earlier standards require this also partitially but there are rules when the compiler is allowed to reorder these data members. Can anyone here tell me which rules apply exactly when ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青芜 2025-02-05 04:20:15

从最新的C ++ 23草稿中:

[expr.rel]

将不平等指针与对象进行比较的结果是根据与以下规则一致的部分顺序定义的:

  • 如果两个指针指向同一对象的不同非静态数据成员,或者指向此类成员的子对象,则需要递归,以后,要求后来声明的成员的指针比较更大他们的班级不是工会。

非静态成员的分配顺序是该规则的必要结果。该规则是由注释引用的:

[class.mem.general]

[注8:非零大小([Into.Object])的非变化的非静态数据成员,因此以后的成员在类对象中具有较高的地址([Expr.rel])。


在提案P1847之前的C ++ 11-20中,规则是:

  • 如果两个指针指向同一对象的不同非静态数据成员,或者指向此类成员的子对象,则需要递归,要求后来声明的成员的指针以更大的范围比较两个成员具有相同的访问控制([class.Access]),这两个成员都不是零大小的子对象,他们的类不是联合。
  • 否则,不需要指针比其他指针更大


C ++ 23的比较,允许编译器重新订购具有不同访问控制的成员。示例:

struct s {
    int a;
protected:
    int b;
};

s ab;
// value of c is implementation dependent in C++20
// value of c is true in C++23
bool c = &ab.a < &ab.b;

主要编译器除声明顺序外,实际上还没有使用其他任何内容。

C ++ 03更加放松,尽管巧妙:

[class.mem]

(非工会)类别的非静态数据成员声明未介入访问指定符,以便
后来的成员在类对象中具有更高的地址。非静态数据成员分配的顺序分开
由访问专业人士未指定(11.1)。


[expr.rel]

  • 如果两个指针指向同一对象的非静态数据成员,或者指向该对象的子对象或数组元素
    递归地,如果两个成员是
    不被访问专业标签(11.1)隔开,并提供其班级不是工会。
  • 如果两个指针指向由访问特征标签隔开的同一对象的非静态数据成员(11.1)
    结果未指定。

From latest C++23 draft:

[expr.rel]

The result of comparing unequal pointers to objects is defined in terms of a partial order consistent with the following rules:

  • If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member is required to compare greater provided neither member is a subobject of zero size and their class is not a union.

The allocation order of non-static members is a necessary consequence of this rule. The rule is referred by a note:

[class.mem.general]

[Note 8: Non-variant non-static data members of non-zero size ([intro.object]) are allocated so that later members have higher addresses within a class object ([expr.rel]).


In C++11-20, prior to the proposal P1847, the rule was:

  • If two pointers point to different non-static data members of the same object, or to subobjects of such members, recursively, the pointer to the later declared member is required to compare greater provided the two members have the same access control ([class.access]), neither member is a subobject of zero size, and their class is not a union.
  • Otherwise, neither pointer is required to compare greater than the other

Pre C++23, compilers are allowed to re-order members with differing access control. Example:

struct s {
    int a;
protected:
    int b;
};

s ab;
// value of c is implementation dependent in C++20
// value of c is true in C++23
bool c = &ab.a < &ab.b;

Major compilers haven't actually used any other than declaration order.

C++03 was even more relaxed, although subtly:

[class.mem]

Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allocated so that
later members have higher addresses within a class object. The order of allocation of non-static data members separated
by an access-specifier is unspecified (11.1).


[expr.rel]

  • If two pointers point to non-static data members of the same object, or to subobjects or array elements of such
    members, recursively, the pointer to the later declared member compares greater provided the two members are
    not separated by an access-specifier label (11.1) and provided their class is not a union.
  • If two pointers point to non-static data members of the same object separated by an access-specifier label (11.1)
    the result is unspecified.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文