Date: Fri, 25 Feb 2022 13:30:18 -0500
On Fri, Feb 25, 2022 at 1:13 PM Jody Hagins <coachhagins_at_[hidden]> wrote:
> 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.
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;
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
> 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.
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;
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
Received on 2022-02-25 18:30:29