Does C++20 remove the requirement for class members to be in ascending order?
Asked Answered
B

1

45

In C++17 there is normative text [class.mem]/17:

Non-static data members of a (non-union) class with the same access control (Clause 14) are allocated so that later members have higher addresses within a class object. The order of allocation of non-static data members with different access control is unspecified.

Also there is [class.mem]/24:

If a standard-layout class object has any non-static data members, its address is the same as the address of its first non-static data member

Here are two examples:

struct A { int x, y, z; } a;
struct F { public: int p; private: int q; public: int r; } f;

According to the above standard text, C++17 guaranteed &a.x < &a.y, &a.y < &a.z, and &f.p < &f.r (but did NOT guarantee &f.p < &f.q, since F is not standard-layout so class.mem/24 does not apply).


However, in C++20 final working draft N4860, there has been a change as per CWG 2404. The [class.mem]/17 has been turned into a Note. However, notes are non-normative in ISO standards (meaning the compiler vendor can disregard them) . And I cannot find any other text that might apply.

My question is: does C++20 still somewhere specify (normatively) the guarantees &a.y < &a.z and/or &f.p < &f.r ? Or does the compiler now have the licence to reorder class members in all cases except for the first subobject of a standard-layout class?

Assuming there are no further changes between N4860 and the published standard, I guess.

Breana answered 4/5, 2020 at 11:3 Comment(0)
S
30

This is still guaranteed by [expr.rel]/(4.2), describing the behavior of built-in <, <=, >, and >= expressions on pointer values.

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.

Sanguine answered 4/5, 2020 at 11:11 Comment(3)
A reference to this should probably be added to the now-a-note [class.mem]/17, to avoid this question occurring again. (I hit the same issue in 2019, but didn't find this answer.)Silden
Since that would be an editorial change, I went ahead and opened a Pull Request to add this reference.Silden
This was in a review auditDenitrify

© 2022 - 2024 — McMap. All rights reserved.