This issue is triggered by: https://github.com/D-Programming-Language/dmd/pull/2561 I have struggled to reduce it though it is rather complicated. SOURCE FILES: *lib.d --------- module lib; void test( string data) { auto ret = new Foo(); ret.data = data; assert(ret.data.length < 1_000_000); // OK! ret.check(); // NG } class Foo { // Removing this or changing order of these members // affects the runtime behavior ... version (defined) { int[int] unusedAA; } string data; void check() { assert(data.length < 1_000_000); // NG! } } *main.d --------- import lib; void main() { string data = "text"; test( data); } COMMANDS(compile and run): dmd.exe -lib -version=defined lib.d dmd.exe -g -inline inlinebug.d lib.lib inlinebug.exe OUTPUT: core.exception.AssertError@lib.d(20): Assertion failure ---------------- 0x00402487 in _d_assert 0x004020DB in void lib.Foo.check() 0x0040206C in _Dmain
Whether inlining the function 'test' or not makes difference. However, other conditions affect strange.
If you use the lib.lib binary, you should emit same version definitions to compile the `main.d`. Otherwise, the class instance size of Foo will be different in each compilation units (lib.d and main.d), then the inlined code will access invalid memory in runtime. In other words, this is expected result. Your compilation steps are just wrong, so the generated execution binary will cause invalid result.
Note that, this is unavoidable issue of the languages which supports separate compilation for old simple linkers. If each compilation units is compiled under different conditions, the consistency of the binaries won't be guaranteed. To do it, we should have "smart linker" that checks the compilation consistency, and add enough meta information into the object files to check it.
I see... thank you. I'll change my mind.