Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
February 14, 2021 Constructor called instead of opAssign() | ||||
---|---|---|---|---|
| ||||
I have generic types that are initialized by a base class for each derived object: struct S(T) { this(T val) { value = 100; } void opAssign(T val) { value = val; } T value; } class A { this(this T)() { foreach (property; __traits(allMembers, T)) { static if (property == "x") { __traits(getMember, cast(T) this, property) = 50; } } } } class B : A { S!int x; this(int val) { assert(x.value == 50); x = val; } } auto b = new B(200); assert(b.x.value == 200); // 100 Although x is well initialized by A by calling opAssign(), the compiler doesn't care and calls the S!T ctor() on B again and opAssign() is ignored. Is this a bug or a rule? |
February 14, 2021 Re: Constructor called instead of opAssign() | ||||
---|---|---|---|---|
| ||||
Posted in reply to frame | On Sunday, 14 February 2021 at 07:09:20 UTC, frame wrote: > Although x is well initialized by A by calling opAssign(), the compiler doesn't care and calls the S!T ctor() on B again and opAssign() is ignored. Is this a bug or a rule? It's a rule described here: https://dlang.org/spec/struct.html#field-init "In a constructor body ... the first instance of field assignment is its initialization." If you assign a second time, it will use the opAssign method. |
February 14, 2021 Re: Constructor called instead of opAssign() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Boris Carvajal | On Sunday, 14 February 2021 at 08:38:49 UTC, Boris Carvajal wrote:
> On Sunday, 14 February 2021 at 07:09:20 UTC, frame wrote:
>> Although x is well initialized by A by calling opAssign(), the compiler doesn't care and calls the S!T ctor() on B again and opAssign() is ignored. Is this a bug or a rule?
>
> It's a rule described here: https://dlang.org/spec/struct.html#field-init
>
> "In a constructor body ... the first instance of field assignment is its initialization."
>
> If you assign a second time, it will use the opAssign method.
The first instance is in A - and why opAssign then works there?
|
February 16, 2021 Re: Constructor called instead of opAssign() | ||||
---|---|---|---|---|
| ||||
Posted in reply to frame | On Sunday, 14 February 2021 at 08:46:34 UTC, frame wrote:
> The first instance is in A - and why opAssign then works there?
Sorry I didn't pay too much attention.
It seems the detection of first assignment only happens when the field and constructor have the same parent, so it doesn't work either if the field is from a base or derived class (your case by means of casting 'this').
I don't think this is intended rather it appears to be a bug/deficiency in the constructor flow analysis of DMD, which from what I'm reading is very rudimentary.
|
February 16, 2021 Re: Constructor called instead of opAssign() | ||||
---|---|---|---|---|
| ||||
Posted in reply to Boris Carvajal | On Tuesday, 16 February 2021 at 09:04:43 UTC, Boris Carvajal wrote:
> I don't think this is intended rather it appears to be a bug/deficiency in the constructor flow analysis of DMD, which from what I'm reading is very rudimentary.
If I'm using a delegate in B, supplied to super() and called in A, then it works :P
|
Copyright © 1999-2021 by the D Language Foundation