Date: Wed, 21 Dec 2022 09:31:13 +0100
On Wed, 21 Dec 2022 at 08:42, Ville Voutilainen <ville.voutilainen_at_[hidden]>
wrote:
> On Wed, 21 Dec 2022 at 09:38, Edward Catmur <ecatmur_at_[hidden]>
> wrote:
> >
> >
> >
> > On Wed, 21 Dec 2022 at 08:29, Ville Voutilainen <
> ville.voutilainen_at_[hidden]> wrote:
> >>
> >> On Mon, 19 Dec 2022 at 14:51, Sébastien Bini <sebastien.bini_at_[hidden]>
> wrote:
> >> >
> >> > On Mon, Dec 19, 2022 at 1:11 PM Ville Voutilainen <
> ville.voutilainen_at_[hidden]> wrote:
> >> >>
> >> >> I don't get it. If we have a new kind of constructor, there is no ABI
> >> >> _break_, since it's just a new constructor. So why aren't you adding
> >> >> such
> >> >> a new constructor for pair?
> >> >>
> >> >> Since this is a semantic facility with semantic guarantees, using
> >> >> attributes here seems like the wrong thing to do.
> >> >
> >> >
> >> > I get your confusion. Let me explain in more detail. Let's say you
> want to call this relocation constructor with a function parameter as
> source object. This function parameter was passed by value to the function:
> >> >
> >> > void bar(T);
> >> > void foo(T val)
> >> > { bar(reloc val); }
> >> >
> >> > To simplify, the reloc call here will call the relocation constructor
> for us. When an object is passed to the relocation constructor, its
> destructor must not be called. So in the example, foo must not call the
> destructor of val. However, if foo's ABI is caller-destroy, then foo
> doesn't have the means of doing that, as it is not in charge of calling the
> destructor of val in the first place.
> >>
> >> The problem goes away if the semantics of destructive move are such
> >> that the destructive-moved-from object is in a state where
> >> destruction is valid but not necessary.
> >
> >
> > Yes; we don't want that, since then we would be unable to use
> relocate-only types such as never-empty types such as not_null<unique_ptr>.
> For another example, guard types often need to be relocatable, but move
> support and an empty state add considerable complexity, often more than
> doubling the amount of code required.
>
> 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.
wrote:
> On Wed, 21 Dec 2022 at 09:38, Edward Catmur <ecatmur_at_[hidden]>
> wrote:
> >
> >
> >
> > On Wed, 21 Dec 2022 at 08:29, Ville Voutilainen <
> ville.voutilainen_at_[hidden]> wrote:
> >>
> >> On Mon, 19 Dec 2022 at 14:51, Sébastien Bini <sebastien.bini_at_[hidden]>
> wrote:
> >> >
> >> > On Mon, Dec 19, 2022 at 1:11 PM Ville Voutilainen <
> ville.voutilainen_at_[hidden]> wrote:
> >> >>
> >> >> I don't get it. If we have a new kind of constructor, there is no ABI
> >> >> _break_, since it's just a new constructor. So why aren't you adding
> >> >> such
> >> >> a new constructor for pair?
> >> >>
> >> >> Since this is a semantic facility with semantic guarantees, using
> >> >> attributes here seems like the wrong thing to do.
> >> >
> >> >
> >> > I get your confusion. Let me explain in more detail. Let's say you
> want to call this relocation constructor with a function parameter as
> source object. This function parameter was passed by value to the function:
> >> >
> >> > void bar(T);
> >> > void foo(T val)
> >> > { bar(reloc val); }
> >> >
> >> > To simplify, the reloc call here will call the relocation constructor
> for us. When an object is passed to the relocation constructor, its
> destructor must not be called. So in the example, foo must not call the
> destructor of val. However, if foo's ABI is caller-destroy, then foo
> doesn't have the means of doing that, as it is not in charge of calling the
> destructor of val in the first place.
> >>
> >> The problem goes away if the semantics of destructive move are such
> >> that the destructive-moved-from object is in a state where
> >> destruction is valid but not necessary.
> >
> >
> > Yes; we don't want that, since then we would be unable to use
> relocate-only types such as never-empty types such as not_null<unique_ptr>.
> For another example, guard types often need to be relocatable, but move
> support and an empty state add considerable complexity, often more than
> doubling the amount of code required.
>
> 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.
Received on 2022-12-21 08:31:25