On Fri, Feb 25, 2022 at 1:13 PM Jody Hagins <coachhagins@gmail.com> wrote:

I've learned to never disagree with you on anything, so I'd like to be correctly corrected :-)

I've always been under the understanding that reordering was only granted ACROSS access control boundaries, but everything within the same access boundary had a strict ordering. [...] I'd find it difficult to see how the compiler could arrange a and b in your example in a different order and still meet this requirement, since they have the same access control level.

Ah, yes, you're correct: `a` and `b` have the same access control, so they can't be reordered (and not even in C++98 because there are no intervening access-control specifiers). Also, I was wrong about the type's being non-standard-layout, too: having a mix of public and private non-static data members would make it non-standard-layout, but merely having a public member function plus some private data members does not make it non-standard-layout. The type I showed was standard-layout. So, double oops.

The C++20 rule you quoted has changed in the working draft, thanks to http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2021/p1847r4.pdf — it's changed to disallow reordering at all, IIUC.
But P1847R4 still gives a good summary of the history AFAICT. It seems that if we look at

struct S {
    int a;
    int b;
    int c;
    int d;
    int e;
    int f;

we have this situation:
C++03 permitted the compiler to lay this out as ABCDEF or ABEFCD or CDABEF or CDEFAB or EFABCD or EFCDAB. (But for sure not BACDEF.)
C++11 eliminated some freedom: it permitted only ABCDEF, ABEFCD, CDABEF. (Question: Did it still permit ACDBEF, ACBDEF, etc? I think so but I'm not sure.) (But for sure not CDEFAB.)
C++23 eliminated all freedom: it permits only ABCDEF. (Right?)

If someone can confirm my understanding of this example, I think it'd be a great candidate for me to blog it. ;)