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.
[class.mem]/17
, to avoid this question occurring again. (I hit the same issue in 2019, but didn't find this answer.) – Silden