Bug 19945 – In betterC strange linker error can occur when importing alias of template struct
Status
RESOLVED
Resolution
INVALID
Severity
normal
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
All
OS
All
Creation time
2019-06-07T04:50:48Z
Last change time
2022-06-04T06:20:43Z
Keywords
betterC
Assigned to
No Owner
Creator
Nathan S.
Comments
Comment #0 by n8sh.secondary — 2019-06-07T04:50:48Z
I reproduced this problem with DMD v2.086.0 and DMD v2.085.1 and LDC 1.15.0. I did not test other versions of DMD or LDC.
### 1. This works with -betterC.
---
extern(C) void main()
{
import std.random : LinearCongruentialEngine;
enum A = 48_271, B = 0, C = 2_147_483_647;
alias MyMinstdRand = LinearCongruentialEngine!(uint, A, B, C);
MyMinstdRand gen;
auto n = gen.front;
}
---
### 2. This works with -betterC.
---
extern(C) void main()
{
import std.random : LinearCongruentialEngine, MinstdRand;
enum A = 48_271, B = 0, C = 2_147_483_647;
alias MyMinstdRand = LinearCongruentialEngine!(uint, A, B, C);
static assert(is(MyMinstdRand == MinstdRand), "definitions are identical");
}
---
### 3. But there is a linker error if they are combined when using -betterC.
---
extern(C) void main()
{
import std.random : LinearCongruentialEngine, MinstdRand;
enum A = 48_271, B = 0, C = 2_147_483_647;
alias MyMinstdRand = LinearCongruentialEngine!(uint, A, B, C);
static assert(is(MyMinstdRand == MinstdRand), "definitions are identical");
MyMinstdRand gen; // error: undefined reference to '_D3std6random__T24LinearCongruentialEngineTkVki48271Vki0Vki2147483647ZQCc6__initZ'
auto n = gen.front; //error: undefined reference to '_D3std6random__T24LinearCongruentialEngineTkVki48271Vki0Vki2147483647ZQCc5frontMxFNaNbNdNiNfZk'
}
---
### 4. The same error occurs with -betterC when trying to use MindstdRand directly.
---
extern(C) void main()
{
import std.random : MinstdRand;
MinstdRand gen; // error: undefined reference to '_D3std6random__T24LinearCongruentialEngineTkVki48271Vki0Vki2147483647ZQCc6__initZ'
auto n = gen.front; // error: undefined reference to '_D3std6random__T24LinearCongruentialEngineTkVki48271Vki0Vki2147483647ZQCc5frontMxFNaNbNdNiNfZk'
}
---
Comment #1 by bugzilla — 2022-06-04T06:02:33Z
The -betterC is for programs that do not use the D runtime library. At link time, the D runtime library is not searched by the linker, only the C runtime library is.
Your example program is using std.random, which is part of the D runtime library. The undefined symbol:
_D3std6random__T24LinearCongruentialEngineTkVki48271Vki0Vki2147483647ZQCc5frontMxFNaNbNdNiNfZk
looks like std.random.LinearCongruentialEngine.front() is not found, which makes sense because that function is in the D runtime library which is not linked in.
_D3std6random__T24LinearCongruentialEngineTkVki48271Vki0Vki2147483647ZQCc6__initZ
is the static initializer for std.random.LinearCongruentialEngine and is also not found because it is in the D runtime library.
If the compile is able to inline everything it needs from the D runtime library, it will work because it then won't need to look in the D runtime library to find it. You'll know when it doesn't work by the appearance of the undefined symbols.
I'm going to mark this as invalid because using the D runtime library in -betterC is not officially supported (even though it may work) since the whole point of -betterC is to not use the D runtime library.
Comment #2 by alphaglosined — 2022-06-04T06:20:43Z
Walter is probably correct that we cannot fix this.
However, it should work due to LinearCongruentialEngine being templated.
For dmd if -allinst makes this code work, then it is indeed a template emission bug.