Move Constructor Syntax

Manu turkeyman at gmail.com
Thu Oct 17 14:56:32 UTC 2024


On Thu, 17 Oct 2024, 23:16 Timon Gehr via Digitalmars-d, <
digitalmars-d at puremagic.com> wrote:

> On 10/17/24 02:05, Manu wrote:
> > On Thu, 17 Oct 2024, 07:36 Timon Gehr via Digitalmars-d, <digitalmars-
> > d at puremagic.com <mailto:digitalmars-d at puremagic.com>> wrote:
> > ...
> >
> >     I agree with Manu's reasoning why having `this(ref S)` and `this(S)`
> >     work as "initialization from lvalue" and "initialization from
> rvalue",
> >     corresponding to copy and move respectively would be cleaner.
> >
> >     But overall I don't have a strong preference, as dedicated syntax
> also
> >     has some benefits. The thing I think is most important is getting the
> >     semantics right.
> >
> >
> > Special-casing the constructor is just admitting that the overload
> > selection mechanics are broken for **all other function calls**... It's
> > not a matter of 'preference'; if the overload mechanics work properly
> > then special casing the constructor wouldn't even be thinkable or raised
> > in conversation. It's a hack; a really dumb hack which just leaves EVERY
> > OTHER FUNCTION broken.
> >
> > The fact you have "no strong preference" surprises me, maybe I've
> > misunderstood some way in which this is not a hack that's totally
> > broken?
>
> There is a tradeoff. I think a `this(S)` has to call the destructor of
> the argument at the end of its scope. This is the right thing to do for
> normal functions, but you might expect a move constructor to not call it
> as it already destroys it as part of its normal operation. DIP1040 tried
> to fix this by _special-casing the constructor_. ;)
>
> With a syntax based on `ref`, it is clear that there will not be a
> destructor call.


But upon very trivial investigation we quickly determined that all
arguments need to be cleaned up; it avoids complicated special cases and
additional attribution. If there's an opportunity for destructor elision,
it would be an advanced optimisation. It shouldn't be the basic semantic
for simplicity's sake... and when you accept that, any complexity around
the design disappears completely.


> Can you explain to me how every other function call isn't broken
> > under the special-case-for-move-constructor solution?
>
> Move semantics still needs a separate solution, but this thread is about
> move constructors. Move constructors are not needed for move semantics,
> they are needed to manually hook moves that involve a transfer of values
> between different memory locations.


They're not 'a thing' though, they are just a natural consequence of move
semantics. Move construction will work naturally given an rvalue
constructor, no special cases, no rules, probably not even one single line
of code in the compiler is necessary once move semantics are working
generally.

I think this is where it's gotten lost...
Move semantics don't need a "separate solution", they are actually the
conversation we're meant to be having.

This talk about move constructors is where it's all gotten lost in the
woods; If move semantics exist, then move constructors don't need "a
solution" at all, they just work naturally with no further intervention.

I'm pretty sure that confusion is the basis for the madness going on
here... people seem to be obsessed with move construction while completely
ignoring or overlooking move semantics in general, or somehow thinking it's
separate or secondary?

So, to belabour the point... move semantics is the primary concept here;
and there should be no "move constructor" as a distinct feature, it's just
a natural consequence of move semantics existing. No conversation about
move constructors is necessary... this is all just leading to confusion.

Reframe thought experiments in terms of `void f(ref T)`, and `void f(T)`,
hopefully that should eliminate confusion. Select the proper overload in
that set when calling f(...), and we're done here.

Please, everyone stop talking about "move constructors"... at least until
you've understood what move semantics are. Get your head around move
semantics, then you will naturally understand how redundant and misleading
this entire conversation about move constructors is...


> Overload selection
> > has to work, it is basically the meat of this whole thing... there's not
> > really anything else to it.
> >
> > Broken calling semantics for every function other than the constructor
> > is not a 'compromise', it baffles me that people would even consider it.
> > I mean, you don't 'call' constructors so often, but you do call
> > everything else.
> >
>
> I am completely with you here.


I know, but once readers understand and accept this, they will also
understand that move constructors aren't "a thing", they're just a normal
constructor with a rvalue as argument, and calling semantics/overload
selection is necessarily the same as any other function.

I think this confusion and noise will all disappear as soon as people
understand this.

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20241018/0e853111/attachment-0001.htm>


More information about the Digitalmars-d mailing list