www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 16956] New: struct .init is generated even for

https://issues.dlang.org/show_bug.cgi?id=16956

          Issue ID: 16956
           Summary: struct .init is generated even for void-initialized
                    structs
           Product: D
           Version: D2
          Hardware: x86_64
                OS: Linux
            Status: NEW
          Severity: enhancement
          Priority: P1
         Component: dmd
          Assignee: nobody puremagic.com
          Reporter: acehreli yahoo.com

Item 1 below is introduction, item 2 is a quality of implementation issue, but
item 3 is more serious.

Assuming the test program is named foo.d, I used the following command line on
a Linux console to determine the symbol sizes in the dmd-produced binary.

  dmd foo.d -c ; nm --print-size --size-sort --radix=d foo.o


1) WORKS AS EXPECTED: The following program does not generate TestStruct.init
in the text section:

struct TestStruct {
    ubyte[10_000] a = void;
}

void main() {
}

$ dmd foo.d -c ; nm --print-size --size-sort --radix=d foo.o | grep -v " B "
[...]
0000000000000000 0000000000000037 T _D3foo8__assertFiZv
0000000000000000 0000000000000039 T _D3foo15__unittest_failFiZv
0000000000000000 0000000000000151 V _D26TypeInfo_S3foo10TestStruct6__initZ

As seen in the output above, TestStruct.init is just 151 bytes (not 10000).


2) THE PROBLEM: Using this type as a class member makes the class have a large
.init:

struct TestStruct {
    ubyte[10_000] a = void;
}

class TestClass {
    TestStruct s = void; // Removing "= void" does not make a difference
}

void main() {
}

$ dmd foo.d -c ; nm --print-size --size-sort --radix=d foo.o | grep -v " B "
[...]
0000000000000000 0000000000000151 V _D26TypeInfo_S3foo10TestStruct6__initZ
0000000000000000 0000000000000168 V _D3foo9TestClass7__ClassZ
0000000000000000 0000000000010016 V _D3foo9TestClass6__initZ

Although TestStruct is void-initialized, this time TestClass.init is 10016
bytes.


3) FURTHER PROBLEM: If the struct is a template, even a *pointer* member in an
aggregate types causes a large TestStruct.init:

struct TestStruct(T) {
    T[10_000] a = void;
}

class TestClass {
    TestStruct!ubyte * t = void; // Removing "= void" does not make a
difference
}

void main() {
}

$ dmd foo.d -c ; nm --print-size --size-sort --radix=d foo.o | grep -v " B "
[...]
0000000000000000 0000000000000168 V _D3foo9TestClass7__ClassZ
0000000000000000 0000000000000168 V
_D46TypeInfo_S3foo18__T10TestStructThZ10TestStruct6__initZ
0000000000000000 0000000000010000 V
_D3foo18__T10TestStructThZ10TestStruct6__initZ

Note: Replacing the 'class' with 'struct' makes no difference in this last
case.

Ali

--
Dec 07 2016