www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - The case of &T.init

reply Marco Leise <Marco.Leise gmx.de> writes:
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 ?

In std.conv we have:

---

//emplace helper functions
private ref T emplaceInitializer(T)(ref T chunk)  trusted pure nothrow
{
    static if (!hasElaborateAssign!T && isAssignable!T)
        chunk = T.init;
    else
    {
        import core.stdc.string : memcpy;
        static immutable T init = T.init;
        memcpy(&chunk, &init, T.sizeof);
    }
    return chunk;
}

---

It seems wasteful to create duplicates of .init, so it would
be nice if one could just write:

  import core.stdc.string : memcpy;
  memcpy(&chunk, &T.init, T.sizeof);

Likewise it would be nice to get the a class's .init[] slice
at compile-time.

-- 
Marco
May 19 2015
next sibling parent "Vladimir Panteleev" <vladimir thecybershadow.net> writes:
On Tuesday, 19 May 2015 at 18:39:43 UTC, 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 ?
No, if the .init of a type is all zero bits then it is not placed in the data segment.
May 19 2015
prev sibling next sibling parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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. 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). 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.
 Likewise it would be nice to get the a class's .init[] slice
 at compile-time.
I think you can: typeid(SomeClass).init -Steve
May 19 2015
parent Marco Leise <Marco.Leise gmx.de> writes:
Am Tue, 19 May 2015 14:52:46 -0400
schrieb Steven Schveighoffer <schveiguy 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
May 19 2015
prev sibling parent Marco Leise <Marco.Leise gmx.de> writes:
 Likewise it would be nice to get the a class's .init[] slice
 at compile-time.
Scratch that part, the compile optimizes typeid(T).init.ptr down to a single load from a fixed address. That's pretty close to knowing and using it statically. -- Marco
May 19 2015