C++ Logo


Advanced search

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

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Fri, 25 Feb 2022 13:46:15 -0500
On Fri, Feb 25, 2022 at 12:30 PM organicoman via Std-Proposals
<std-proposals_at_[hidden]> wrote:
> Keep in mind that objects are guaranteed to be destroyed in the opposite order of construction. If you have multiple constructors that may construct your subobjects in different orders, you must also allocate run-time memory to record the order of initialization in order for your destructor to destroy the objects in the correct order. That's an unacceptable cost to a lot of people.
> What you are talking about here, and i guess most of the participant in this discussion, is the base classes of a derived class (known as subobjects).
> For that case. Yes, the order of destruction MUST follow the order of construction in reverse, and that is guaranteed by the standard.
> In our case we are talking about " MEMBER Objects", objects declared inside the body of the structure.

Members are a *kind* of subobject.

> The compiler is free to rearrange their layout however it sees fit for a compact memory and to avoid extra instruction to fetch a member if it is not at the right memory boundary.

The compiler is permitted to insert padding, but it's permitted to do
that for *any* subobject, base or member. What the compiler is *not*
allowed to do is rearrange the *order* of members entirely. There are
cases where the compiler can, but since C++11, that is restricted
specifically to cases where some members are of different access
classes, and this reordering can only happen *between* members of
different access classes. Within an access classes, later members must
come after earlier ones.

This is explicitly codified in C++20's pointer comparison rules:

> If two pointers point to different non-static data members of the same object, or to subobjects of such
members, recursively, the pointer to the later declared member is
required to compare greater provided
the two members have the same access control (11.9), neither member is
a subobject of zero size, and
their class is not a union.

So your conclusion arises from faulty premises. The layout of a struct
must be such where later declared members are later in the object than
earlier ones, within the same access control. Ordering is not subject
to the compiler's whims.

Received on 2022-02-25 18:46:25