C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Relax condition for potentially invoked destructor in constructor

From: Jody Hagins <coachhagins_at_[hidden]>
Date: Fri, 25 Feb 2022 14:27:06 -0500
From 1998...

 • 12 Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allo- cated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment require- ments might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).


From 2003 (which looks identical to 1998 wording, including section numbers)


 • 12 Nonstatic data members of a (non-union) class declared without an intervening access-specifier are allo- cated so that later members have higher addresses within a class object. The order of allocation of nonstatic data members separated by an access-specifier is unspecified (11.1). Implementation alignment require- ments might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).


Based on that, any intervening access specifier (even the same one) can permit reordering, which always seemed to be a bit crazy... so much so that I forgot about it until you reminded me in your post...



From 2011/2014/2017 - almost identical wording, not repeated for brevity...

 • 14 Nonstatic data members of a (non-union) class with the same access control (Clause 11) 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 (11). Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (10.3) and virtual base classes (10.1).


From 2020 - slight change...

 • 19 [Note: Non-static data members of a (non-union) class with the same access control (11.9) and non-zero size (6.7.2) 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. Implementation alignment requirements might cause two adjacent members not to be allocated immediately after each other; so might requirements for space for managing virtual functions (11.7.2) and virtual base classes (11.7.1). —end note]



Thus, I'd think that ACDBEF, ACBDEF are indeed permitted. It only states that the addresses have to come higher - not that variables of other access specifiers can't be interleaved - as long as they preserve increasing addresses within the same access specifier.


From 2023 draft...

 • 20 [Note 8: Non-variant non-static data members of non-zero size (6.7.2) are allocated so that later members have higher addresses within a class object (7.6.9). Implementation alignment requirements can cause two adjacent members not to be allocated immediately after each other; so can requirements for space for managing virtual functions (11.7.3) and virtual base classes (11.7.2). —end note]


This one pretty much gets rid of any reordering at all since there is no qualification except that later members have higher addresses.








> On Feb 25, 2022, at 1:30 PM, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]> wrote:
>
> On Fri, Feb 25, 2022 at 1:13 PM Jody Hagins <coachhagins_at_[hidden] <mailto: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 <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 19:27:10