Arthur,
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.
But P1847R4 still gives a good summary of the history AFAICT. It seems that if we look at
struct S {
int a;
int b;
private:
int c;
int d;
public:
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. ;)
–Arthur