Discussion Thread: DIP 1040--Copying, Moving, and Forwarding--Community Review Round 1
tsbockman
thomas.bockman at gmail.com
Fri Mar 12 23:47:20 UTC 2021
On Friday, 5 March 2021 at 12:19:54 UTC, Mike Parker wrote:
> This is the discussion thread for the first round of Community
> Review of DIP 1040, "Copying, Moving, and Forwarding":
The default field-wise move operators seem to have been specified
with no concern for maintaining consistency between the semantics
of custom operators and default operators:
From the DIP:
> If a Move Assignment Operator is not defined for a struct that
> has a Move Constructor, a default Move Assignment Operator is
> defined and implemented as a move for each of its fields, in
> lexical order.
If a custom move constructor is present for a good reason, that
means that simply moving the fields one-by-one is *not* the
desired move behavior.
Instead, the default move assignment operator should call the
struct's move constructor and destructor in one of the two valid
patterns that I found earlier in this discussion (link to a full
working example):
https://gist.github.com/run-dlang/b789714c01905f091a44ee2666276433
// Using an alternative syntax so that this can be tested today:
void moveAssign(ref S source) @trusted nothrow @nogc {
static if(useDIPLowering) {
// destroy after (the DIP's proposal):
S newVal = void;
newVal.moveConstruct(source);
S oldVal = void;
oldVal.moveConstruct(this);
moveConstruct(newVal);
// Implicitly destruct(oldVal).
} else {
// conditionally move and destroy before (my proposal):
if(&source !is &this) {
destruct(this);
moveConstruct(source);
}
}
}
Also from the DIP:
> If a Move Constructor is not defined for a struct that has a
> Move
> Assignment Operator, a default Move Constructor is defined and
> implemented as a move for each of its fields, in lexical order.
Again, the presence of a custom move assignment operator
indicates that non-default move behavior is desired.
Auto-generating a default move constructor is a missed
opportunity to point out a semantic inconsistency in the user's
work.
Defining a custom move assignment operator without a custom move
constructor to go with it should be a compile-time error, because
there is no automated way to extract a valid move constructor
from a custom move assignment operator.
In the unlikely case that the omission of the custom move
constructor is intentional, people can manually defining a
field-wise move constructor (which is not difficult), or annotate
that constructor with @disable.
More information about the Digitalmars-d
mailing list