Large .init for class containing void-initialized struct

Basile B. via Digitalmars-d digitalmars-d at puremagic.com
Tue Dec 6 18:10:59 PST 2016


On Wednesday, 7 December 2016 at 00:20:11 UTC, Ali Çehreli wrote:
> tl;dr; go to the TLDR section below. :)
>
> [...]
>
> struct S {
>     int i = void;
>     double d = void;
>     ubyte[10_000] a = void;
> }
>
> class C {
>     S s = void; // (Same result even without the =void)
> }
>
> void main() {
> }
>
> [...]
> 0000000004446260 0000000000003633 T 
> _D4core4time8Duration13_toStringImplMxFNaNbNfZAya
> 0000000004505140 0000000000003707 T _d_arraysetlengthiT
> 0000000006681456 0000000000010032 V _D6deneme1C6__initZ
>
> Now we have a 10032 byte C.init.
>
> Is there a rationale for this or is this an implementation 
> quality issue? Is there a bug already? I could not find one.
>
> Also, I failed to find the "= void" documentation e.g. not on 
> the struct spec page.
>
> Thank you,
> Ali

Non initialized classes just don't work. Because of the hidden 
classes fields an initializer is **always** needed. What happens 
in your example is that the initializer size is sub optimal.

A naive make without emplace():

====
import std.traits, std.c.stdlib;

CT make(CT, A...)(A a)
{
     auto memory = malloc(__traits(classInstanceSize, CT));
     version(none) 
emplace!Foo(memory[0..__traits(classInstanceSize, CT)]);
     static if (__traits(hasMember, CT, "__ctor"))
         (cast(CT) (memory)).__ctor(a);
     return cast(CT) memory;
}

class Foo{void foo(){}}

void main()
{
     Foo foo = make!Foo;
     foo.foo;
}
====

crashes with a segfault....


More information about the Digitalmars-d mailing list