C++ Logo

std-proposals

Advanced search

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

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Tue, 23 Aug 2022 18:25:37 +0100
On Tue, 23 Aug 2022 at 12:40, Sébastien Bini <sebastien.bini_at_[hidden]>
wrote:

> On Mon, Aug 22, 2022 at 10:08 PM Edward Catmur <ecatmur_at_[hidden]>
> wrote:
>
>> On Mon, 22 Aug 2022 at 14:36, Sébastien Bini <sebastien.bini_at_[hidden]>
>> wrote:
>>
>>> I'm in favor of the default operator to be aliased. However this is not
>>> enough as if the assignment operator of each subclass is not aliased, then
>>> you may still end-up making that many copies (or relocations).
>>>
>>> I believe we do need to provide a way to clearly annotate the assignment
>>> operator as aliased (that reloc keyword comes in). Also, it would serve for
>>> assignment operators that are defaulted in the implementation file only.
>>>
>>
>> I contend that it's enough to mandate aliasing for relocatable-by-ABI
>> types. Note that this doesn't affect ABI in that the callee still does the
>> same amount of work; the difference is that the caller is required to
>> observe that the source and target cannot alias and that therefore the
>> parameter can alias the source instead of having to be a relocated
>> temporary.
>>
>
> If I understand correctly, you suggest that aliasing be mandated only for
> types that have a relocation constructor and have not opted-out of the ABI
> break? I like this idea, it further avoids another keyword in the operator
> declaration.
>
> But what about trivial types, which follow the rule of zero?
>
> struct S { int _d; S& operator=(S rhs) { _d = rhs._d; return *this; } };
>
> They will get a relocation constructor for free, even if none of their
> subobjects explicitly provides a relocation constructor. Had they declared
> a prvalue-assignment operator, then it would change its ABI silently. It's
> okay for them to silently go from caller-destroy to callee-destroy as their
> destructor is a no-op, but aliasing will also force the parameter to share
> the same address as the caller's site source object, which is a silent ABI
> break.
>

It's not always an ABI break. On all 64-bit ABIs that I'm aware of (see
https://www.agner.org/optimize/calling_conventions.pdf), the caller is
responsible for allocating and cleaning up stack space used by oversized /
non-trivial objects, so the callee doesn't need to know whether aliasing is
occurring.

On the other hand, it is an ABI break on most 32-bit ABIs. But your
example struct doesn't even follow the rule of zero (once relocating
assignment becomes a special member function), so maybe it would be OK if
aliasing doesn't occur in that specific case. In fact, it's quite possible
that the presence of a user-declared relocating assignment operator would
suppress the relocating constructor, so it definitely wouldn't be a
candidate for aliasing?

Received on 2022-08-23 17:25:50