Move Constructor Syntax

Manu turkeyman at gmail.com
Sat Oct 12 23:45:29 UTC 2024


On Sun, 13 Oct 2024, 08:01 Timon Gehr via Digitalmars-d, <
digitalmars-d at puremagic.com> wrote:

> On 10/12/24 10:06, Manu wrote:
> >
> >     4. rvalue constructors exist and are used, and are NOT move
> constructors
> >
> >
> > They are rvalue constructors; it doesn't matter what they do, their
> > selection criteria remains identical.
>
> Just as long as the semantics of the actual declaration does not change.
> DIP1040 proposed to change the semantics of the move constructor
> declaration itself.
>
> Anyway, I agree that a clean design may be that a constructor that
> accepts an lvalue of the same type should be a copy constructor and a
> constructor that accepts an rvalue of the same type should be a move
> constructor (templated or not). Without any special semantics of the
> declaration itself.
>
> Then standard overload resolution (with an after-the-fact check whether
> there is `ref` on the first parameter) can be used to check whether
> something is copyable or moveable.
>
>
> I guess one change in behavior is that code that previously worked with
> implicit compiler-generated moves or explicit moves will now invoke
> something that had been written as an rvalue constructor, which also
> precluded there being any user-defined copy constructor in the struct or
> its fields (disabled or otherwise).


Yes, that's the case in question. We need to see some case studies; I have
a suspicion that much code that makes sense and is not actually a bug is
actually already some kind of move constructor.
The calling rules choosing a compiler-generated move or an rvalue
constructor are murky (because they are both perfect match; there much be a
hard coded tie-breaker, and it must be circumstantial), and I bet any code
that uses that is brittle and subject to very special care when handling.


I am not sure for what purpose rvalue constructors are even being
> written today, but I think the only way to invoke them is as an explicit
> `S(s)`.


Maybe, and that might be the definition of the hard-coded tie-breaker rule
I described a moment ago... It's non-uniform in any event, a complete
surprise that there would be 2 separate cases.

If someone does something funky in such a constructor, it may
> not actually do the right thing if it suddenly starts being called for
> moves.
>

Maybe. Let's find out!
I wouldn't worry about it... It's already a bad API pattern that depends on
weird and brittle rules.

What the hell could it reasonably mean to initialise an S from another S
and not be some kind of move when written in your code exactly the way you
expect a move to appear?
I think if we find examples in the wild either a) it's already a move in
waiting, or b) it's actually broken and the author didn't realise.

My bet is that instances of this code were written by inexperienced D
programmers who probably had a poor understanding around the semantics of
what they wrote.

But let's find out! We need case studies relating to this super weird and
frankly nonsense pattern.
In any event, if this is the only breaking change we encounter, then we're
in amazingly good shape!
I will submit the PR to correct every project that suffers from this
myself...

>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.puremagic.com/pipermail/digitalmars-d/attachments/20241013/21a0c08c/attachment.htm>


More information about the Digitalmars-d mailing list