Generating struct .init at run time?
Ali Çehreli
acehreli at yahoo.com
Thu Jul 2 07:51:29 UTC 2020
Normally, struct .init values are known at compile time. Unfortunately,
they add to binary size:
enum elementCount = 1024 * 1024;
struct S {
double[elementCount] a;
}
void main() {
S s;
assert(typeid(S).initializer.length == double.sizeof * elementCount);
assert(typeid(S).initializer.ptr !is null);
}
Both asserts pass: S.init is 800M and is embedded into the compiled program.
Of course, the solution is to define members with '= void':
enum elementCount = 1024 * 1024;
struct S {
double[elementCount] a = void; // <-- HERE
}
void main() {
S s;
assert(typeid(S).initializer.length == double.sizeof * elementCount);
assert(typeid(S).initializer.ptr is null);
}
Now the program binary is 800M shorter. (Note .ptr is now null.) Also
note that I did NOT use the following syntax because there is a dmd bug:
auto s = S(); // Segfaults:
https://issues.dlang.org/show_bug.cgi?id=21004
My question is: Is there a function that I can call to initialize 's' to
the same .init value that compiler would have used:
S sInit;
shared static this() {
defaultInitValue(&sInit); // Does this exist?
}
I can then use sInit to copy over the bytes of all S objects in the
program. (Both the structs and their object instantiations are all
code-generated; so there is no usability issue. There are thousands of
structs and the current binary size is 2G! :) )
If not, I am planning on writing the equivalent of defaultInitValue()
that will zero-init the entire struct and then overwrite float, double,
char, wchar, and dchar members with their respective .init values,
recursively. Does that make sense?
Ali
More information about the Digitalmars-d-learn
mailing list