On Wed, Dec 21, 2022 at 9:52 AM Ville Voutilainen <ville.voutilainen@gmail.com> wrote:
On Wed, 21 Dec 2022 at 10:31, Edward Catmur <ecatmur@googlemail.com> wrote:
>> So, rather than have a destructive move where such a semantic
>> restriction would be in place, do you prefer not having destructive
>> move at all?
>
> That seems to me a false dichotomy; there is no reason whatsoever why we couldn't have both. As noted elsewhere, the only types for which callee-destroy is an absolute necessity are those which are relocate-only, which currently cannot be passed by value at all, so if implementations choose they can retain ABI compatibility for all class types which can currently be passed by value, even when adding a relocating constructor, trivial or otherwise.

I don't know whether it's a dichotomy, I'm merely trying to figure out
which pieces of this cake are up for bargaining.
I grok the practical need to relocate a container just fine, it's far
less clear to me why I need
to relocate a reloc-only type, or even introduce the concept of a
reloc-only type. What happens if I reloc-move an object and
then try to access it? Is that yet another source of UB? I spy with my
little eye that if the semantic restriction I ruminate on there
is present, that source of UB isn't necessarily introduced.

relocate-only types are already a thing, but are unusable. Consider for instance non_null<unique_ptr>. There are also user-defined types that today implement move-semantics but have an unnatural empty state. If they don't implement move-semantics, then they are often wrapped around an optional or unique_ptr, so the wrapper handles the moved-from state for them. Those types will be candidates to be relocate-only.

Relocation will happen with the new reloc keyword (or new series of symbols if we don't want a keyword). That keyword will mark the end of scope of the relocated object, so that it cannot be reused after being relocated. The program is ill-formed if a relocated object is reused. This is not perfect as we only track the relocated object, and not all the potential references to it that still exist. But those issues are inherent to the language, as you can already have references on destroyed objects in C++.