Thread overview
Missing Symbol Accessing Templated Function Through Interface
Mar 08, 2016
Peter
Mar 08, 2016
Nicholas Wilson
Mar 08, 2016
crimaniak
Mar 08, 2016
Peter
March 08, 2016
Hi,

Can anyone explain to me what's causing the following code to generate a missing symbol error...

import std.stdio;

interface IProblem {
   void writeln(T...)(T arguments);
}

class Problem : IProblem {
   void writeln(T...)(T arguments) {
      // This is just here to have code in an implementation.
      stdout.writeln("The implementation function was called.");
   }
}

IProblem getProblem() {
   return(new Problem());
}

void main() {
   auto problem = getProblem();

   problem.writeln("Some text and a number - ", 1234);
}

Now obviously this codes a bit contrived but its my attempt to reduce an issue I'm seeing to its more concise form. Note that if I cast the return value from the call to getProblem() to a Problem instance this rectifies the issue but I'm unclear as to why this might be. The error I get when I compile this is...

   Undefined symbols for architecture x86_64:
     "_D3app8IProblem18__T7writelnTAyaTiZ7writelnMFAyaiZv", referenced from:
         __Dmain in template_issue.o
   ld: symbol(s) not found for architecture x86_64
   clang: error: linker command failed with exit code 1 (use -v to see invocation)
   --- errorlevel 1
   dmd failed with exit code 1.

Apologies is the cause is blatantly obvious to more experienced D coders.

Regards,

Peter
March 08, 2016
On Tuesday, 8 March 2016 at 11:50:32 UTC, Peter wrote:
> Hi,
>
> Can anyone explain to me what's causing the following code to generate a missing symbol error...
>
> import std.stdio;
>
> interface IProblem {
>    void writeln(T...)(T arguments);
> }
>
> class Problem : IProblem {
>    void writeln(T...)(T arguments) {
>       // This is just here to have code in an implementation.
>       stdout.writeln("The implementation function was called.");
>    }
> }
>
> IProblem getProblem() {
>    return(new Problem());
> }
>
> void main() {
>    auto problem = getProblem();
>
>    problem.writeln("Some text and a number - ", 1234);
> }
>
> Now obviously this codes a bit contrived but its my attempt to reduce an issue I'm seeing to its more concise form. Note that if I cast the return value from the call to getProblem() to a Problem instance this rectifies the issue but I'm unclear as to why this might be. The error I get when I compile this is...
>
>    Undefined symbols for architecture x86_64:
>      "_D3app8IProblem18__T7writelnTAyaTiZ7writelnMFAyaiZv", referenced from:
>          __Dmain in template_issue.o
>    ld: symbol(s) not found for architecture x86_64
>    clang: error: linker command failed with exit code 1 (use -v to see invocation)
>    --- errorlevel 1
>    dmd failed with exit code 1.
>
> Apologies is the cause is blatantly obvious to more experienced D coders.
>
> Regards,
>
> Peter

Probably because the idea of a template function in an interface is
wrong, and I'm surprised that dmd accepts that. The reason is that
declaring a (non final)template function in an interface is like declaring a
function pointer to an uninstansiated(sp?) template function. Also
how many copies should appear in the vtbl for different template
argument combinations?
 Calling a templates on a class is fine, which explains why casting
solves the issue.

Solutions: if the function in the interface must take template args
parameterise the interface not the function (not sure if this works)
OR
if the function must take a variable number of args just use regular
runtime varadic arguments.

Nic
March 08, 2016
On Tuesday, 8 March 2016 at 11:50:32 UTC, Peter wrote:
> Hi,
>
> Can anyone explain to me what's causing the following code to generate a missing symbol error...

Relevant comment: https://issues.dlang.org/show_bug.cgi?id=8553#c1

March 08, 2016
On Tuesday, 8 March 2016 at 12:24:06 UTC, crimaniak wrote:
> On Tuesday, 8 March 2016 at 11:50:32 UTC, Peter wrote:
>> Hi,
>>
>> Can anyone explain to me what's causing the following code to generate a missing symbol error...
>
> Relevant comment: https://issues.dlang.org/show_bug.cgi?id=8553#c1

Thanks for link, makes sense.