C++ Logo

std-proposals

Advanced search

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

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Mon, 30 May 2022 11:56:35 -0600
On Mon, 30 May 2022 at 11:25, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
wrote:

> On Mon, May 30, 2022 at 12:53 PM Edward Catmur <ecatmur_at_[hidden]>
> wrote:
>
>> On Mon, 30 May 2022 at 10:23, Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
>> wrote:
>>
>>> On Mon, May 30, 2022 at 11:37 AM Edward Catmur via Std-Proposals <
>>> std-proposals_at_[hidden]> wrote:
>>>
>>>>
>>>> We expect there to exist types that are immovable and [non-trivially]
>>>> relocatable.
>>>>
>>>
>>> FWIW, I (in P1144) consider that an oxymoron. A type that is
>>> immobile/immovable cannot be relocatable, because it's not movable.
>>> Immobility is for types that cannot be moved from place to place — like
>>> `std::mutex`, for example.
>>>
>>
>> That's the strongest version of immovability; types that must occupy the
>> same storage throughout their lifetime. But there are weaker versions where
>> a class type has no copy or move constructor but is nevertheless
>> relocatable: [e.g.]
>> - types that have invariants that preclude having an empty state
>> (gsl::non_null)
>>
>> Perhaps it would help to introduce terminology distinguishing the strong
>> case from the weaker case? Say, "immobile" for the strong case and
>> "immovable" for the weaker case? Or, just "non-semiregular" for the weaker
>> case, if you'd prefer.
>>
>
> I strongly discourage making any Memmi/Derrida–style subtle distinctions
> between the words "immobile" and "immovable."
>
> I suggest phrases like "types that have an `operator reloc` but no move
> constructor" (describing the physical situation) or "types that are
> conceptually movable but lack any moved-from state" (describing the
> conceptual situation).
>

Well, yes, but that's a bit of a mouthful, so people will come up with a
more concise terminology, or at best an initialism.

If you want to permit "types that are conceptually movable but lack any
> moved-from state," then you need to flesh out the semantics of operations
> like assignment and swapping. I've seen a lot in this thread about
> relocating-into-a-constructor, but not much IIRC about
> relocating-into-an-assignment or swapping-by-relocating.
>
> gsl::non_null<int*> p1, p2, p3 = ...;
> gsl::non_null<int*> q1 = reloc p1; // OK in your world
> q1 = reloc p2; // OK??
> std::swap(q1, p3); // OK??
>
> *Conceptually*, all of these operations should be legal, right? None of
> them leave a gsl::non_null<int*> object in a moved-from state. Can your
> `operator reloc` actually handle all of them, though? (This would go in
> the paper.)
>

1. Yes.
2. Yes.
3. Yes, if gsl::non_null writes a swap overload, but also std::swap could
destroy and recreate its arguments:

template<class T> requires std::is_noexcept_relocatable_v<T>
void swap(T& lhs, T& rhs) {
    T temp = relocate_at(&lhs);
    new (&lhs) T(relocate_at(&rhs));
    new (&rhs) T(relocate_at(&temp));
}

(relocate_at is the magic library function that (destroys and) relocates
its argument into a returned prvalue.)


> The advantage of a syntax is that you can express trivial relocation
>> simply by defaulting it, and it Does The Right Thing if any member becomes
>> non-trivial.
>>
>
> Pedantic terminology nit: Just like with any other special member,
> `=default` on your `operator reloc` wouldn't mean it was *trivial*; it
> would just mean it was *defaulted*, i.e., *memberwise*.
> struct A { std::string s; operator reloc(A&&) = default; }; // memberwise
> and trivial
> struct B { std::any a; operator reloc(B&&) = default; }; // memberwise
> and non-trivial
>

Absolutely, yes; and that's an advantage, since it means that a memberwise
(defaulted) relocation operation is trivial precisely when each subobject
is trivially relocatable; you won't end up making mistakes when changing
data members or if another programmer changes the semantics of a type that
you use.

Aside: is std::string necessarily trivially relocatable? I seem to remember
in the old days some SSO strings that used self-reference, but maybe no
library implementor has gone for that strategy.

Received on 2022-05-30 17:56:47