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