Large .init for class containing void-initialized struct

Ali Çehreli via Digitalmars-d digitalmars-d at puremagic.com
Tue Dec 6 16:20:11 PST 2016


tl;dr; go to the TLDR section below. :)

I use the following command line to identify large symbols. Given a 
binary named 'deneme', the following command line (at least on Linux) 
produces the 30 largest symbols in the 'deneme' binary that actually 
take space in application's memory:

   nm --print-size --size-sort --radix=d deneme | tail -30 | grep -v " B "

A test program:

struct S {
     int i;
     double d;
     ubyte[10_000] a;
}

void main() {
}

According to the command line above, the largest symbol in that program 
is S.init:

[...]
0000000004446100 0000000000003633 T 
_D4core4time8Duration13_toStringImplMxFNaNbNfZAya
0000000004504980 0000000000003707 T _d_arraysetlengthiT
0000000004511312 0000000000010016 R _D6deneme1S6__initZ

So, the S.init object in that binary is 10016 bytes and that makes sense.

Now, request S.init not be generated by initializing the members with void:

struct S {
     int i = void; // (Actually, this =void is not required)
     double d = void;
     ubyte[10_000] a = void;
}

void main() {
}

Great: Now the large S.init is not a part of the binary: (Well, I think 
it's still in the BSS section but it does not take space in the memory):

[...]
0000000004446100 0000000000003633 T 
_D4core4time8Duration13_toStringImplMxFNaNbNfZAya
0000000004504980 0000000000003707 T _d_arraysetlengthiT

The largest symbol is now something else: _d_arraysetlengthiT. Here 
comes the trouble...

TLDR:

Use the void-initialized struct as a class member and that class gets a 
huge C.init:

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


More information about the Digitalmars-d mailing list