The case of &T.init

Marco Leise via Digitalmars-d digitalmars-d at puremagic.com
Tue May 19 21:24:08 PDT 2015


Am Tue, 19 May 2015 14:52:46 -0400
schrieb Steven Schveighoffer <schveiguy at yahoo.com>:

> On 5/19/15 2:40 PM, Marco Leise wrote:
> > I was wondering why T.init is treated as a manifest constant.
> > Don't all .init's end up in some data segment with a
> > resolvable address ?
> 
> Because T.init IS a manifest constant. In other words, doing:
> 
> T t = T.init;
> 
> Generates code to initialize t. It doesn't copy the data from some init 
> value stored in ROM.

Mhm. That allows the compiler optimize around "holes" (skip `=
void` initializers). But still, while it doesn't copy from
ROM, TypeInfo.init is mostly not-null, so there is still .init
copy placed in ROM that we just cannot access from D code!

> Note, there is a place T.init is stored, and that is in typeid(T).init. 
> However, it's not always there (could be null if T.init is all zero).

I knew that about null once .. a year ago or so. Thanks for
the reminder.

> What we could do, however, is make one copy of an addressable T.init:
> 
> template initialValue(T)
> {
>     static immutable T initialValue = T.init;
> }
> 
> that was used wherever it's needed, instead of creating a new one for 
> every time you need it.

Yeah, why not. On second thought it is probably ok to let the
compiler chose the optimal assignment strategy: assign only
fields which are not void-initialized, memcpy from ROM or
zero-fill. Whether DMD is doing that at the moment is another
question, but I'm all for letting the compiler handle the
dirty details.

I guess what I was really looking for is a way to tell the
compiler that my `T* t` is uninitialized or "raw" and I want
it initialized like the compiler would do with a `T t` on the
stack: `t` is not destructed, nor is opAssign called on it.
Potentially "optimal" code is generated to satisfy the .init
state.

-- 
Marco



More information about the Digitalmars-d mailing list