Getting the default value of a class member field

kinke noone at nowhere.com
Thu Dec 1 23:02:31 UTC 2022


On Thursday, 1 December 2022 at 08:09:05 UTC, WebFreak001 wrote:
> I've got this class definition:
>
> ```d
> class X
> {
>     this()
>     {
>         assert(false);
>     }
>
>     int x = 3;
> }
> ```
>
> due to internal reasons the constructor would fail at compile 
> time, so I put in an assert(false) here, and I can't add or 
> change any methods in X.
>
> How do I get `3` if I have `X` and field name `"x"` at compile 
> time?
>
> For structs `X.init.x` / `__traits(getMember, X.init, "x")` 
> would work, however for classes it complains about null 
> dereference.
>
> I saw there is __traits(initSymbol), however that one doesn't 
> work at compile time.

AFAIK, there is no way. Unlike a struct's init symbol, a class' 
one doesn't necessarily represent a valid instance state - it's 
just the raw payload before invoking a ctor (which constructs a 
valid instance), and the state 'dead' memory is reset to after 
finalizing an object instance (to prevent dead pointers keeping 
other GC refs alive).

If the ctor worked at CTFE, one could use:
```d
int get() {
     scope x = new X;
     return x.x;
}
enum bla = get();
```
to get the `x` value of a *valid* instance, which might be 
different than the static initializer (if modified in the ctor).

I guess the main question is why do you require the static 
initializers of these fields at compile-time. 
`__traits(initSymbol)` was added to aid in manual blitting at 
runtime.


More information about the Digitalmars-d-learn mailing list