www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Weird link error

reply "CodeSun" <cscodesun gmail.com> writes:
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
next sibling parent "Adam D. Ruppe" <destructionator gmail.com> writes:
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
prev sibling next sibling parent "anonymous" <anonymous example.com> writes:
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
prev sibling parent "Baz" <bb.temp gmx.com> writes:
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