D issues are now tracked on GitHub. This Bugzilla instance remains as a read-only archive.
Issue 16956 - struct .init is generated even for void-initialized structs
Summary: struct .init is generated even for void-initialized structs
Status: NEW
Alias: None
Product: D
Classification: Unclassified
Component: dmd (show other issues)
Version: D2
Hardware: x86_64 Linux
: P4 enhancement
Assignee: No Owner
URL:
Keywords: industry
Depends on:
Blocks:
 
Reported: 2016-12-07 18:29 UTC by Ali Cehreli
Modified: 2024-12-13 18:50 UTC (History)
2 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this issue.
Description Ali Cehreli 2016-12-07 18:29:25 UTC
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
Comment 1 Walter Bright 2019-12-23 09:09:22 UTC
Partial solution:

https://github.com/dlang/dmd/pull/10682
https://github.com/dlang/dmd/pull/10680
Comment 2 dlangBugzillaToGithub 2024-12-13 18:50:53 UTC
THIS ISSUE HAS BEEN MOVED TO GITHUB

https://github.com/dlang/dmd/issues/17783

DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB