Field Initialiser Reused Across Object Instances

Adam D. Ruppe destructionator at gmail.com
Fri Jan 1 14:06:10 UTC 2021


On Friday, 1 January 2021 at 13:34:16 UTC, Adam wrote:
>     A a = new A; // I would expect this to be called for each 
> "new B".

Your expectation is wrong for D. Since that's in a `static` 
context, it is run at compile time.

Any variable marked `static`, `__gshared`, or is 
struct/class/module-top-level member is a static context. So all 
those are set up at compile time (or triggers a compile error if 
this fails btw, either a thing is a static context and thus CTFEd 
or not a static context and thus never CTFEd) and just blindly 
copied at run time.

Basically any assignment outside a function is a compile time 
thing.

> Is this intended?

Yes, it is a frequent thing to surprise people though. The 
reference there is part of the object but it points to the same 
default thing because of how that was made.

Constructors are actually run at runtime, but initializers are 
considered compile time constants.

>  My gut reaction is the compiler is memoising "new A" because 
> purity is inferred

note that ctfe never happens because of anything inferred or pure 
or stuff like that. It is purely decided by the initialization 
context.

> I can fix using a dedicated constructor, but I much prefer 
> initializers where possible.

no real choice here, if you want a unique object to be referenced 
it needs to run with the constructor.


More information about the Digitalmars-d-learn mailing list