Move Constructor Syntax
Timon Gehr
timon.gehr at gmx.ch
Wed Oct 16 18:21:46 UTC 2024
On 10/16/24 15:39, Arafel wrote:
> On 16.10.24 15:06, Timon Gehr wrote:
>
>> With Walter's current preferred design, a new dummy object is created
>> in the old memory location. I.e., it has to be valid, but it does not
>> have to contain any data.
>
> [...]
>
>> A key difference between `this(S s)` and `=this(ref S)` is that the
>> latter elides the destructor by default, while for the former, the
>> least surprising semantics would be that it calls the destructor of
>> the source at the end of the scope by default. There would then need
>> to be an additional feature to elide the destructor call with manual
>> syntax.
>
> Let me go back to my original example, slightly modified to make my
> point more clear:
>
>
> ```d
> struct S {
> int i;
> this(C)(C c) if (is(C : int)) {
> this.i = c;
> }
>
> alias i this;
> }
>
> void main() {
> S s1, s2, s3;
> int i = 1;
> s1 = S(1);
> s2 = S(i);
> s3 = S(s2); // This was most certainly not intended as a move
> constructor.
> assert(s2.i == 1);
> assert(s3.i == 1);
> }
> ```
>
> Would this code still be guaranteed to pass the asserts if the signature
> for move constructors becomes `this (S s)` (Walter's proposal)? I mean
> based on assurances by the language itself, not on what the compiler
> might decide to do (or not) with s2.
Yes, I think the sane design is that if you pass an lvalue to an rvalue
parameter, that results in a copy (during argument passing), and the
copy is destroyed when it goes out of scope in the constructor.
So if you explicitly call an rvalue constructor, that would behave the
same as previously.
Even with the unamended DIP1040, I think assertion failures would not
fire in your example. The way DIP1040 might break such code is if `S`
has a destructor.
More information about the Digitalmars-d
mailing list