digitalmars.D.learn - Undefined symbol for, apparently, valid code?
- unleashy (35/35) Jul 05 2017 Hello. I am trying to compile this:
- rikki cattermole (4/48) Jul 05 2017 Templates+classes = require function body.
- Arafel (19/22) Jul 06 2017 Well, it happened to me once [1], and the reason is that templated
- unleashy (9/16) Jul 06 2017 Ah well. I would've expected a compiler error, not an obscure
- Arafel (17/26) Jul 06 2017 I think an "abstract" class is only one that cannot be directly
- H. S. Teoh via Digitalmars-d-learn (11/36) Jul 06 2017 [...]
- unleashy (9/13) Jul 06 2017 `dmd --version` outputs:
- H. S. Teoh via Digitalmars-d-learn (6/22) Jul 06 2017 [...]
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 2017
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 2017
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 2017
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 2017
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 2017
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 2017
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 2017
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:[...] Looks like it. T -- My program has no bugs! Only undocumented features...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 2017