C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Relocation in C++

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Sun, 22 May 2022 17:32:30 -0600
On Sun, 22 May 2022 at 13:14, Jason McKesson via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> On Sun, May 22, 2022 at 12:46 PM Edward Catmur via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
> >
> > On Fri, 20 May 2022 at 18:52, Thiago Macieira <thiago_at_[hidden]>
> wrote:
> >>
> >> I don't think that's sufficient. The change needs to be opt-in, not
> opt-out.
> >> Otherwise, we're going to have silent breakages because of some
> libraries
> >> recompiled and others not.
> >
> >
> > Uh, if a library is not recompiled, then it uses the old ABI, and if it
> is recompiled then either it's compiled against old source code, so uses
> the old ABI, or is compiled against new source code with relocation
> operator defined but also with the opt-out in place, so it uses the old ABI.
>
> I think his point was that you're confusing the terms "opt-in" and
> "opt-out".
>
> For a feature to be "opt-in", it must be unavailable *unless* you do a
> thing that specifically makes it available to you. "Opt-out" is the
> *opposite*; you have the feature *unless* you do a thing to turn it
> off.
>
> The deletion behavior of defaulted move constructors in the presence
> of user-provided copy constructors is an example of "opt-in". If your
> type has a user-provided copy constructor, but you don't declare a
> move constructor (maybe because you wrote it in C++98/03 where those
> didn't exist), then your type's move constructor will be deleted. It
> cannot participate in moves. Your type doesn't have a move operation
> unless you explicitly ask for one.
>
> That seems to be what you're arguing for here, just with the wrong
> terminology. You are describing "opt-in" functionality, but you *call*
> it "opt-out".
>

There is both opt-in and opt-out under this scheme. First, a nontrivial
class opts *in* to relocation (trivial or otherwise), by declaring (and
possibly defaulting) a relocation operation. This opt-in is necessary since
nontrivial classes cannot be assumed to be automatically relocatable (they
may need self-reference fixup, etc.). Next, it opts *out* of the ABI
change, by annotating the relocation operation with an attribute. This
opt-out means that the class is passed into functions as if it did not
declare the relocation operation, so this is compatible with previously
compiled code and with code compiled to an earlier standard version with
the relocation operation #if defined out.

A function parameter of a type that has opted out of the ABI change may
still be the argument of the relocation operator keyword, but this will
move construct the target from the source parameter (unless the relocation
operator expression is a discarded-value expression) and defer destruction
of the parameter to (after) the end of the function, instead of invoking
the relocation operation and not destroying the function parameter. A
function parameter of a class that opts out of ABI change but has no
accessible move constructor cannot be relocated within the function.

The reason to opt in *and* opt out is that this permits relocation to be
used in other situations than function argument passing, esp. containers
(e.g. vector reallocate) but also relocation of automatic variables and of
class subobject bases and members.

Both opt-in and opt-out propagate to derived and composing classes as
necessary to maintain the Rule of Zero. ABI break (opt-in without opt-out)
also propagates (a class that breaks ABI for itself is assumed responsible
for breaking the ABI of derived and composing classes) but can be canceled
by the derived/composing class itself opting out.

Received on 2022-05-22 23:32:43