Move Constructor Syntax

Walter Bright newshound2 at digitalmars.com
Thu Oct 10 07:09:34 UTC 2024


On 10/8/2024 10:42 PM, Manu wrote:
> Can you show us some cases?

I'd get infinite recursion with overload resolution, because the compiler will 
try and match the argument to `S` and `ref S`, made even more complicated with 
rvalue references enabled.

The compiler would go into infinite recursion converting a ref to an rvalue and 
back to a ref again. There were maybe 10 or more functions in the recursion 
stack, looping through the heavy semantic routines.

Another problem was failure to compile libmir:
```
source/mir/rc/ptr.d(395,15): Error: `mir.rc.ptr.castTo` called with argument 
types `(mir_rcptr!(C))` matches both:
   source/mir/rc/ptr.d(275,13):     `mir.rc.ptr.castTo!(I, 
C).castTo(mir_rcptr!(C) context)`
   and:
   source/mir/rc/ptr.d(291,25):     `mir.rc.ptr.castTo!(I, 
C).castTo(immutable(mir_rcptr!(C)) context)`

```
If libmir breaks, that means other code will break, too. I eventually decided it 
was not a good idea to modify existing semantics (rvalue constructors exist and 
are used already), as who knows how much breakage that would ensue. Adding 
distinct syntax for the new semantics seemed like a much more practical approach.

I.e. `this(S)` already is accepted by the compiler and is used.


> The story you present is incomplete, let me enhance:
> 
> struct S { ... }
> struct Other { ... }
> 
> this(ref S) // copy constructor
> this(this)  // postblit
> this(S)     // move constructor
> ~this()     // destructor

It's not that simple. You can have:

```
alias T = S;
this(T);     // can't tell if move constructor by syntax
```

> this(Other) // move from other (Other is an rvalue here)
> this(ref Other) // copy from other (Other is obviously a ref)

Problems show up when `Other` is implicitly convertible to `S`.

> Likewise, I don't understand why opMove would be necessary to distinguish from 
> opAssign?

Is `a = b` a move or a copy?

> If you introduce opMove, then you'll end up with opIndexMove, opOpMove, etc.
> Is that something you want? Assuming you want to avoid this; then I also imagine 
> solving for that issue would equally solve for the main constructor case?

This is why I don't like implicit conversions for a struct - you wind up with 
impossible tangles of meaning. Oh, and rvalue to ref conversions, too.



More information about the Digitalmars-d mailing list