www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Undefined symbol for, apparently, valid code?

reply unleashy <lakeavenger gmail.com> writes:
Hello. I am trying to compile this:

---
module asd.asd;

abstract class Asd
{
     void opCall(Args...)(Args args);
}

 system unittest
{
     class Foo : Asd
     {
         override void opCall(Args...)(Args args)
         {
             /* nothing */
         }
     }

     Asd a = new Foo();

     a(1, 2, 3);
}
---

This file is under source/asd/asd.d and I'm compiling with `dmd 
-unittest -main -ofasd.exe source\asd\asd.d -m32 -g` under 
Windows x64. For some reason, after the successful compilation 
step, the linker then complains:

---
OPTLINK (R) for Win32  Release 8.00.17
Copyright (C) Digital Mars 1989-2013  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
asd.obj(asd)
  Error 42: Symbol Undefined 
_D3asd3asd3Asd17__T6opCallTiTiTiZ6opCallMFiiiZv
Error: linker exited with status 1
---

Am I doing something wrong, or is this a linker bug?

Thanks!
Jul 05
next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 06/07/2017 7:28 AM, unleashy wrote:
 Hello. I am trying to compile this:
 
 ---
 module asd.asd;
 
 abstract class Asd
 {
      void opCall(Args...)(Args args);
 }
 
  system unittest
 {
      class Foo : Asd
      {
          override void opCall(Args...)(Args args)
          {
              /* nothing */
          }
      }
 
      Asd a = new Foo();
 
      a(1, 2, 3);
 }
 ---
 
 This file is under source/asd/asd.d and I'm compiling with `dmd 
 -unittest -main -ofasd.exe source\asd\asd.d -m32 -g` under Windows x64. 
 For some reason, after the successful compilation step, the linker then 
 complains:
 
 ---
 OPTLINK (R) for Win32  Release 8.00.17
 Copyright (C) Digital Mars 1989-2013  All rights reserved.
 http://www.digitalmars.com/ctg/optlink.html
 asd.obj(asd)
   Error 42: Symbol Undefined 
 _D3asd3asd3Asd17__T6opCallTiTiTiZ6opCallMFiiiZv
 Error: linker exited with status 1
 ---
 
 Am I doing something wrong, or is this a linker bug?
 
 Thanks!
Templates+classes = require function body. Why? Templated methods are not virtual, they are final and cannot be inherited (so its a little strange that the override is valid).
Jul 05
next sibling parent Arafel <er.krali gmail.com> writes:
Well, it happened to me once [1], and the reason is that templated 
functions are final by default (since, as you said, it doesn't make 
sense for them to be anything else).

This way the body of the function is assumed to be in a different 
compilation unit (which is not, hence the linker error). If the variable 
had been declared of type "Foo" instead of "Asd" it would probably had 
worked, although this kind of defeat the purpose.

Whether it makes sense that this construction is allowed, is a different 
question. I personally it makes sense to have the user explicitly ask 
for "final", since we have otherwise "virtual by default", so this 
behaviour is completely unexpected be most users. The whole thing makes 
even less sense if you take into account that a explicit request to 
override is just silently ignored.

Finally, have also in mind that if the function had been declared 
abstract (as it arguably should), a compile-time error would have been 
generated [2].

[1]: http://forum.dlang.org/post/kgxwfsvznwzlnhrdplkc forum.dlang.org
[2]: https://dpaste.dzfl.pl/22f7e0840f01




On 07/06/2017 08:48 AM, rikki cattermole wrote:
 Templates+classes = require function body.

 Why? Templated methods are not virtual, they are final and cannot be
 inherited (so its a little strange that the override is valid).
Jul 06
prev sibling parent reply unleashy <lakeavenger gmail.com> writes:
On Thursday, 6 July 2017 at 06:48:57 UTC, rikki cattermole wrote:
 Templates+classes = require function body.

 Why? Templated methods are not virtual, they are final and 
 cannot be inherited (so its a little strange that the override 
 is valid).
Ah well. I would've expected a compiler error, not an obscure linker error, but as Arafel said:
Finally, have also in mind that if the function had been 
declared abstract (as it arguably should), a compile-time error 
would have been generated [2].
Maybe it was an error on my part for not declaring the function as abstract? My view was that the abstract attribute on a class marks all its members as virtual unless they have a body, which is how it works in, say, Java. Still, kinda odd that the linker is the one to call me out, and not the compiler. Pretty unexpected.
Jul 06
parent Arafel <er.krali gmail.com> writes:
On 07/06/2017 05:11 PM, unleashy wrote:

 
 Maybe it was an error on my part for not declaring the function as 
 abstract? My view was that the abstract attribute on a class marks all 
 its members as virtual unless they have a body, which is how it works 
 in, say, Java.
 
 Still, kinda odd that the linker is the one to call me out, and not the 
 compiler. Pretty unexpected.
 
I think an "abstract" class is only one that cannot be directly instantiated, only through a derived class. It might be "complete", though. This doesn't mean (and that's the confusion) that there couldn't be a function with a body defined in another compilation unit. In java there are no forward declarations, so there is no ambiguity here: a bodyless method means an abstract method. In D a bodyless method can mean: * An abstract method (to be provided by derived classes), which of course must then be virtual. This is indicated with the keyword "abstract". * A method whose body is provided by some other compilation unit. Of course, an abstract class without abstract methods isn't usually the intended idea... But the compiler will silently accept it and let the linker complain afterwards. Again, "final by default" to me is more confusing when anything else, specially when it's usually "virtual by default"... and it's clearly a bug that it compiles after explicitly overriding!
Jul 06
prev sibling parent reply "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Jul 06, 2017 at 06:28:11AM +0000, unleashy via Digitalmars-d-learn
wrote:
 Hello. I am trying to compile this:
 
 ---
 module asd.asd;
 
 abstract class Asd
 {
     void opCall(Args...)(Args args);
 }
 
  system unittest
 {
     class Foo : Asd
     {
         override void opCall(Args...)(Args args)
         {
             /* nothing */
         }
     }
 
     Asd a = new Foo();
 
     a(1, 2, 3);
 }
 ---
[...] Template functions cannot be virtual, and it's invalid to override a non-virtual function. Which version of the compiler are you using? I just tested on the latest dmd git HEAD, and it (correctly) tells me that it's illegal to override a non-virtual function. I'm surprised you got your code to compile at all. T -- My program has no bugs! Only unintentional features...
Jul 06
parent reply unleashy <lakeavenger gmail.com> writes:
On Thursday, 6 July 2017 at 16:16:17 UTC, H. S. Teoh wrote:
 Which version of the compiler are you using?  I just tested on 
 the latest dmd git HEAD, and it (correctly) tells me that it's 
 illegal to override a non-virtual function.  I'm surprised you 
 got your code to compile at all.
`dmd --version` outputs: --- DMD32 D Compiler v2.074.1 Copyright (c) 1999-2017 by Digital Mars written by Walter Bright --- I downloaded it 3 days ago, for Windows. It's not git HEAD, but it's the one available for download in the homepage. Thankfully, it seems fixed for the next version then?
Jul 06
parent "H. S. Teoh via Digitalmars-d-learn" <digitalmars-d-learn puremagic.com> writes:
On Thu, Jul 06, 2017 at 06:49:51PM +0000, unleashy via Digitalmars-d-learn
wrote:
 On Thursday, 6 July 2017 at 16:16:17 UTC, H. S. Teoh wrote:
 Which version of the compiler are you using?  I just tested on the
 latest dmd git HEAD, and it (correctly) tells me that it's illegal
 to override a non-virtual function.  I'm surprised you got your code
 to compile at all.
`dmd --version` outputs: --- DMD32 D Compiler v2.074.1 Copyright (c) 1999-2017 by Digital Mars written by Walter Bright --- I downloaded it 3 days ago, for Windows. It's not git HEAD, but it's the one available for download in the homepage. Thankfully, it seems fixed for the next version then?
[...] Looks like it. T -- My program has no bugs! Only undocumented features...
Jul 06