using .init reliably

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Fri Aug 26 02:48:00 PDT 2016


On Friday, August 26, 2016 08:59:55 Cauterite via Digitalmars-d-learn wrote:
> How can I get the initial value of an arbitrary type? Since any
> struct can override it, .init is not reliable:
>
> struct Z {
>   enum init = 6;
>   string val = `asdf`;
> };
> assert(Z.init == 6);
> assert(typeof(Z()).init == 6);
>
> I know I could use
> *(cast(Z*) typeid(Z).initializer.ptr)
> but that doesn't work in CTFE (because the typeinfo doesn't exist
> yet).
>
> Z() is obviously not reliable either since it can override static
> opCall.

Nothing should ever override init. If it does, then it should be fixed so
that it doesn't. It was an oversight that it was ever allowed, and I believe
that there's a bug report for it. You're supposed to be able to depend on
.init existing. Default initialization for structs can be disabled via

@disable this();

but even then, the init member still exists (it just isn't used for default
initialization). All types have an init property, and it's critical that
that be the case. There's a lot of code (including in druntime and Phobos)
which relies on that fact. So, just use .init, and if a type incorrectly
defines init, then it's just not going not play nicely, and it needs to be
fixed. And I expect that it will become an error at some point in the future
to define an init member for a user-defined type, at which point, there
won't be any choice about fixing it.

- Jonathan M Davis



More information about the Digitalmars-d-learn mailing list