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

Timon Gehr timon.gehr at gmx.ch
Thu Mar 18 18:12:02 UTC 2021


On 18.03.21 10:07, Walter Bright wrote:
> On 3/16/2021 3:30 PM, deadalnix wrote:
>> This is self evident. This is so obvious that I don't know how to 
>> unpack it any further.
> 
> I'm sorry, I just don't understand your objection.

In condensed form, I think the main complaint is this. Let's start with 
a struct:

struct S{
     T field0;
     this(S r){
         field0=move(r.field0);
     }
}


Now someone adds a new field, but forgets to update the move constructor:

struct S{
     T field0, field1;
     this(S r){
         field0=move(r.field0);
     }
}

field1 is now leaked: _Its destructor will never run_. And this can 
happen in @safe code. (Ignoring the issue that field1 of the moved 
object will be the init value.)

This design is error-prone. postblit does not have this issue, because 
fields that are not explicitly referred to are moved correctly by default.

Hence the suggestion in my previous post to perhaps require all fields 
to be initialized in a move constructor and similar thoughts about opAssign.
This mitigates the risk, but unfortunately it does not eliminate it. (It 
is furthermore possible that such an error would be annoying in some cases.)


A possible scenario is:

1. There is a struct S, it's never moved around, so the move constructor 
is dead code.

2. Someone adds a new field, everything works fine, even when they 
forget to update the move constructor.

3. The compiler is updated to use more clever flow analysis, suddenly 
struct S is sometimes moved, leading to memory leaks and other bugs.

4. Spurious regression bug report, reputation damage, etc.



(PS: Sorry for emails that went to your inbox instead of the newsgroup. 
Thunderbird changed the interface for no reason.)


More information about the Digitalmars-d mailing list