Discussion Thread: DIP 1040--Copying, Moving, and Forwarding--Community Review Round 1

tsbockman thomas.bockman at gmail.com
Sat Mar 6 18:42:27 UTC 2021


On Friday, 5 March 2021 at 23:32:04 UTC, Paul Backus wrote:
> On Friday, 5 March 2021 at 23:03:57 UTC, tsbockman wrote:
>> From the DIP:
>>> A Move Constructor for struct S is declared as:
>>>     this(S s) { ... }
>>> A Move Assignment Operator for struct S is declared as:
>>>     void opAssign(S s) { ... }
>>
>> Is the parameter to these methods really pass-by-value?
>>
>> If so, why???
>
> 1) When you pass an rvalue to a by-value parameter in D, it's 
> moved, not copied.

This is good to know, but doesn't solve the problem I asked 
about; it just makes it more complicated. According to the DIP, 
lvalues are moved in some circumstances also, not just rvalues.

So, the move constructor and move assignment operator taking 
their argument by value thus imply that every custom move 
operation *either* infinitely recurses (for rvalues), *or* 
triggers a redundant copy (for lvalues).

> 2) If you have a by-ref overload and a by-value overload for 
> the same function, the ref one is called for lvalues and the 
> by-value one is called for rvalues.

You seem focused on overload selection, but I'm asking what would 
actually happen when the move operator is called:

1) Does it copy the data to a temporary, or not?
2) Is the address of the move operator's argument the address of 
the original value to be moved, or not?

The currently proposed syntax implies that the answers are (1) 
yes and (2) no, but I think the answers need to be (1) no and (2) 
yes for sanity, performance, and flexibility reasons. For 
example, knowing the source address for the move would allow the 
move operator to actually tell whether something is an interior 
pointer that needs to be updated, or not.

> In fact, this is already how you have to write your opAssign if 
> you want to support explicit move-assignment from rvalues of 
> non-copyable types. See for example SumType's opAssign overload 
> [1], and the corresponding unit test [2].

It's the move constructor, which we don't have yet, that implies 
infinite recursion 
(https://issues.dlang.org/show_bug.cgi?id=20424). Also, this 
proposal is about adding proper support for custom move operators 
to the language, because what we have right now isn't good 
enough. So, "that's how it works now" isn't a compelling reason 
to keep doing it that way.


More information about the Digitalmars-d mailing list