Missing Symbol Accessing Templated Function Through Interface
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
Re: Missing Symbol Accessing Templated Function Through Interface
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.
Array operations with array of structs
Hi, I have a struct with arithmetic operations defined using opBinary but array operations with arrays of it don't work. struct Vector3 { public double[3] _p; ... Vector3 opBinary(string op)(in Vector3 rhs) const if (op == "+"){ Vector3 result; result._p[] = this._p[] + rhs._p[]; return result; } ... } unittest{ auto a = Vector3([2.0, 2.0, 0.0]); auto b = Vector3([1.0, 2.0, 1.0]); Vector3[] c = [a]; Vector3[] d = [b]; Vector3 e = a + b; // works Vector3[] f; f[] = c[] + d[]; // Error: invalid array operation 'f[] = c[] + d[]' because Vector3 doesn't support necessary arithmetic operations } how can I get this to work? Thanks
Re: Array operations with array of structs
On Monday, 6 July 2015 at 10:29:35 UTC, anonymous wrote: Works for me with various versions of dmd on linux. What compiler are you using, what version of it, what operating system, etc? dmd 2.066.1, windows 7 64bit
Re: Array operations with array of structs
On Monday, 6 July 2015 at 15:48:28 UTC, anonymous wrote: Ok, I disabled everything in the struct except what I posted and it ran. I then uncommented stuff to isolate the cause. I've added in the bits that cause the error below (plus some constructors just for reference). struct Vector3 { public double[3] _p; @nogc this(in double[] p) { switch ( p.length ) { case 0: _p[0] = _p[1] = _p[2] = 0.0; break; case 1: _p[0] = p[0]; _p[1] = _p[2] = 0.0; break; case 2: _p[0] = p[0]; _p[1] = p[1]; _p[2] = 0.0; break; default: _p[0] = p[0]; _p[1] = p[1]; _p[2] = p[2]; break; } } @nogc this(in double p0, in double p1=0.0, in double p2=0.0) { _p[0] = p0; _p[1] = p1; _p[2] = p2; } @nogc this(in Vector3 other) { _p[] = other._p[]; } //... Vector3 opBinary(string op)(in Vector3 rhs) const if (op == "+"){ Vector3 result; result._p[] = this._p[] + rhs._p[]; return result; } // The bits that cause the error: //... Enabling any one (or more) of the following causes the error this(this) { _p = _p.dup; } @nogc ref Vector3 opAssign(ref Vector3 rhs) { _p[] = rhs._p[]; return this; } @nogc ref Vector3 opAssign(Vector3 rhs) { _p[] = rhs._p[]; return this; } //... } Any ideas about what's happening?
Re: Array operations with array of structs
On Wednesday, 8 July 2015 at 06:05:54 UTC, ketmar wrote: do you see the gotcha? if you uncomment postblit or assigns, this build function fails to compile, as that operations aren't "pure nothrow @nogc @trusted", and they will be used for either assign or postblitting. So after looking into it a little bit... It looks like the opAssigns can take all the attributes without throwing errors so that's good. The postblit can only not take @nogc due to the array duplication which is understandable. I think the postblit might be redundant anyway since the struct is built on a static array so there is no possibility of two different Vect3s "pointing" to the same data. Can someone confirm or does the postblit do anything else?
Re: Array operations with array of structs
On Saturday, 11 July 2015 at 13:31:12 UTC, Peter wrote: So after looking into it a little bit... So now I'm trying to multiply the array by a double but it's giving incompatible type errors. opBinary, opBinaryRight, and opOpAssign are defined. I have: struct Vector3 { public double[3] _p; @nogc this(in double[] p){ switch ( p.length ) { case 0: _p[0] = _p[1] = _p[2] = 0.0; break; case 1: _p[0] = p[0]; _p[1] = _p[2] = 0.0; break; case 2: _p[0] = p[0]; _p[1] = p[1]; _p[2] = 0.0; break; default: _p[0] = p[0]; _p[1] = p[1]; _p[2] = p[2]; break; } } @nogc this(in double p0, in double p1=0.0, in double p2=0.0){ _p[0] = p0; _p[1] = p1; _p[2] = p2; } @nogc this(in Vector3 other){ _p[] = other._p[]; } Vector3 opBinary(string op)(in Vector3 rhs) const if (op == "+") { Vector3 result; result._p[] = this._p[] + rhs._p[]; return result; } Vector3 opBinary(string op)(in double rhs) const if (op == "*") { Vector3 result; result._p[] = this._p[] * rhs; return result; } Vector3 opBinaryRight(string op)(in double lhs) const if (op == "*") { Vector3 result; result._p[] = this._p[] * lhs; return result; } //... pure nothrow @trusted @nogc ref Vector3 opAssign(ref Vector3 rhs) { _p[] = rhs._p[]; return this; } pure nothrow @trusted @nogc ref Vector3 opAssign(Vector3 rhs) { _p[] = rhs._p[]; return this; } @nogc ref Vector3 opOpAssign(string op)(in double rhs) if (op == "*") { this._p[] *= rhs; return this; } //... } unittest{ auto a = Vector3([2.0, 2.0, 0.0]); auto b = Vector3([1.0, 2.0, 1.0]); Vector3[] c = [a]; Vector3[] d = [b]; Vector3 e = a + b; //fine Vector3[] f; f[] = c[] + d[]; //fine e = 2*a; //fine e = 3.0*a; //fine f[] = 2*c[]; //Error: incompatible types for ((2) * (c[])): 'int' and 'Vector3[]' f[] = 3.0*c[]; //Error: incompatible types for ((3.0) * (c[])): 'double' and 'Vector3[]' }