This reduced code fails to link. // foo.d extern(C) int main(){ if("a" == "a") return 1; char[] p; auto a = cast(int[])p; return 0; } A linker error results: Undefined symbols for architecture x86_64: "__D4core8internal5array8equality__T8__equalsTaTaZQoFNaNbNiNeMxAaMxQeZb", referenced from: _main in foo.o ld: symbol(s) not found for architecture x86_64 clang: error: linker command failed with exit code 1 (use -v to see invocation) Error: /usr/bin/cc failed with status: 1 The undefined symbol demangles to: pure nothrow @nogc @trusted bool core.internal.array.equality.__equals!(char, char).__equals(scope const(char[]), scope const(char[])) I have verified this problem happens both with dmd and ldc2. ldc2 1.24 - 1.28 has the error. Older ldc do not. Current dmd has the error, I don’t know how far back.
(In reply to dave287091 from comment #0) > This reduced code fails to link. I forgot to mention, compile with -betterC. Without -betterC it links fine.
(In reply to dave287091 from comment #1) > (In reply to dave287091 from comment #0) > > This reduced code fails to link. > > I forgot to mention, compile with -betterC. Without -betterC it links fine. Also, without the array cast there it also links fine.
This worked with dmd 2.093 and stopped working with dmd 2.094.
The -allinst/--allinst flag will resolve the link error, but that is a counter-intuitive requirement as there is no explicit template in the program - just one injected by the compiler. The fact that array equality is implemented as a template is an implementation detail and shouldn’t require the user to work around it. It’s also weird that the cast somehow changes whether the template is emitted.
It seems that the cast is lowered to __ArrayCast which in turn ends up instantiating __equals with the same template parameters, but in a speculative context (static if). Somehow, the template emission strategy decides that the instance does not require codegen (from what I can tell, the compiler decides that it's better to put the instance in the imported module - core.memory in this case), hence the linker errors. I think that this strategy should be disabled in the case of betterC as it currently is with -allinst.
@RazvanN7 created dlang/dmd pull request #15404 "Fix Issue 22427 - betterC: casting an array causes linker error in string comparison" fixing this issue: - Fix Issue 22427 - betterC: casting an array causes linker error in string comparison https://github.com/dlang/dmd/pull/15404
dlang/dmd pull request #15404 "Fix Issue 22427 - betterC: casting an array causes linker error in string comparison" was merged into master: - bab58df92fa67c4702bf001c8258ff2eeb4643bc by RazvanN7: Fix Issue 22427 - betterC: casting an array causes linker error in string comparison - 9e1ba7b233a73941ec094d60b226af92618301d8 by RazvanN7: Fix Issue 22427 - betterC: casting an array causes linker error in string comparison https://github.com/dlang/dmd/pull/15404