digitalmars.D.learn - Weird link error
- CodeSun (36/36) Apr 20 2015 I have test a snippet of code, and I encountered with a weird
- Adam D. Ruppe (4/6) Apr 20 2015 You can, but they are considered final so a body is required to
- anonymous (36/72) Apr 20 2015 Template methods are non-virtual. That is, you can't override
- Baz (6/9) Apr 20 2015 ---
I have test a snippet of code, and I encountered with a weird link error. The following is the demo: import std.stdio; interface Ti { T get(T)(int num); T get(T)(string str); } class Test : Ti { T get(T)(int num) { writeln("ok"); } T get(T)(string str) { writeln(str); } } void main() { Ti tt = new Test; tt.get!string("test"); tt.get!string(123); } When I use dmd to compile this code snippet, the following link error was reported: tt.d:(.text._Dmain+0x3b):‘_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya’ undefined reference tt.d:(.text._Dmain+0x49):‘_D2tt2Ti12__T3getTAyaZ3getMFiZAya’undefined reference And if I modigy the code to Test tt = new Test; then this code will work. So does it mean I can't declare function template inside interface? If so, why didn't dmd report the error while compiling instead of linking? And where I can find the D symbol definition, because information like ‘_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya’ makes me really confused.
Apr 20 2015
On Monday, 20 April 2015 at 17:02:18 UTC, CodeSun wrote:So does it mean I can't declare function template inside interface?You can, but they are considered final so a body is required to use them - they aren't just a pointer to the derived implementation.
Apr 20 2015
On Monday, 20 April 2015 at 17:02:18 UTC, CodeSun wrote:I have test a snippet of code, and I encountered with a weird link error. The following is the demo: import std.stdio; interface Ti { T get(T)(int num); T get(T)(string str); } class Test : Ti { T get(T)(int num) { writeln("ok"); } T get(T)(string str) { writeln(str); } } void main() { Ti tt = new Test; tt.get!string("test"); tt.get!string(123); } When I use dmd to compile this code snippet, the following link error was reported: tt.d:(.text._Dmain+0x3b):‘_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya’ undefined reference tt.d:(.text._Dmain+0x49):‘_D2tt2Ti12__T3getTAyaZ3getMFiZAya’undefined reference And if I modigy the code to Test tt = new Test; then this code will work.Template methods are non-virtual. That is, you can't override them.So does it mean I can't declare function template inside interface? If so, why didn't dmd report the error while compiling instead of linking?You can theoretically implement them elsewhere. For example, this works: ---- module test; interface Ti { T get(T)(int num); T get(T)(string str); } pragma(mangle, "_D4test2Ti12__T3getTAyaZ3getMFiZAya") string impl(int) { return "foo"; } pragma(mangle, "_D4test2Ti12__T3getTAyaZ3getMFAyaZAya") string impl(string) { return "bar"; } class Test : Ti {} void main() { Ti tt = new Test; tt.get!string("test"); tt.get!string(123); } ---- It's really silly, though. I don't know if there's a more realistic use case.And where I can find the D symbol definition, because information like ‘_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya’ makes me really confused.That's a mangled name. There's a tool called ddemangle. It comes with the D releases. You can pipe the compiler output through it to get more readable symbol names (don't forget to redirect stderr to stdout). For this one it gives gives you "immutable(char)[] tt.Ti.get!(immutable(char)[]).get(immutable(char)[])".
Apr 20 2015
On Monday, 20 April 2015 at 17:02:18 UTC, CodeSun wrote:And where I can find the D symbol definition, because information like ‘_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya’ makes me really confused.--- import std.demangle; auto friendlySymbol = demangle("_D2tt2Ti12__T3getTAyaZ3getMFAyaZAya"); ---
Apr 20 2015