Move Constructor Syntax

Jonathan M Davis newsgroup.d at jmdavisprog.com
Sun Oct 20 09:07:14 UTC 2024


On Saturday, October 5, 2024 10:04:28 PM MDT Walter Bright via Digitalmars-d 
wrote:
> ```
> struct S { ... }
>
> this(ref S) // copy constructor
> this(this)  // postblit
> this(S)     // move constructor
> ~this()     // destructor
>
> alias T = S;
> this(T);    // also move constructor
>
> alias Q = int;
> this(Q);    // regular constructor
> ```
> As the above illustrates, a move constructor cannot be distinguished from a
> regular constructor by syntax alone. It needs semantic analysis.
>
> While this seems simple enough, it isn't I have discovered to my chagrin.
> The overload rules in the language (including things like rvalue references
> where sometimes an rvalue becomes an lvalue) that the move constructors get
> confused with the copy constructors, leading to recursive semantic loops
> and other problems.
>
> I've struggled with this for days now.
>
> A fix that would simplify the language and the compiler would be to have a
> unique syntax for a move constructor, instead of the ambiguous one in the
> proposal. That way, searching for a copy constructor will only yield copy
> constructors, and searching for a move constructor will only yield move
> constructors. There will be a sharp distinction between them, even in the
> source code. (I have seen code so dense with templates it is hard to figure
> out what kind of constructor it is.)
>
> Something like one of:
> ```
> 1. =this(S)
> 2. this(=S)
> 3. <-this(S)
> ```
> ?
>
> It may take a bit of getting used to. I kinda prefer (1) as it is sorta like
> `~this()`.

I don't know what the current state things is with what you're planning to
do with opAssign and moves, but upon thinking further about the issues with
move constructors - and dealing with code at Symmetry which has templated
opAssigns - it occurs to me that opAssign has the same sort of issues as
move constructors do if you try to make opAssign(typeof(this) rhs) do move
assignment like the DIP talks about. Existing code could easily break - be
it silently or not - and there could be some pretty weird results. I've
already had quite a few issues along those lines due to the fact that copy
constructors look like normal constructors. That being the case, I'm very
much inclined to argue that the move assignment operator should have its own
syntax and not just move constructors.

So, either we should probably use something like @move on both move
constructors and move assignment operators, or we should have something like
opMoveAssign instead of opAssign for move assignment (with =this or whatever
for copy constructors). I very much don't want to fight issues with existing
code doing wonky things just because move constructors or move assignment
operators get added.

On a related note, we need to make sure that move construction and move
assignment work correctly with dynamic arrays and AAs. I was shocked to find
out recently that dynamic arrays and AAs do _not_ work properly with copy
constructors. TypeInfo was never updated to take copy construction into
account, and the only druntime hooks that deal with it properly are the ones
which have been templated. The result is that using copy constructiors is
currently very error-prone, and we need to not do the same thing with move
constructors.

- Jonathan M Davis





More information about the Digitalmars-d mailing list