Date: Wed, 21 Dec 2022 10:29:11 +0100
On Wed, Dec 21, 2022 at 9:52 AM Ville Voutilainen <
ville.voutilainen_at_[hidden]> wrote:
> On Wed, 21 Dec 2022 at 10:31, Edward Catmur <ecatmur_at_[hidden]>
> 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++.
ville.voutilainen_at_[hidden]> wrote:
> On Wed, 21 Dec 2022 at 10:31, Edward Catmur <ecatmur_at_[hidden]>
> 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++.
Received on 2022-12-21 09:29:23