Thread overview | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
October 03, 2014 Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
This is under Linux 64 with both dmd 2.066 (and latest gdc-4.9): ================================================================= class ShapeSurface(T) { public: int formula(); int getSurfaceBy100() { int surface; surface = cast(T *)this.formula(); return surface*100; }; }; class Square: ShapeSurface!Square { public: int squareSize = 8; override int formula() { return squareSize*squareSize; } }; int main() { Square square = new Square(); square.getSurfaceBy100(); return 0; } ================================================================= It fails with linker error: dmd app.d app.o:(.data._D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSurface6__vtblZ+0x28): undefined reference to `_D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSurface7formulaMFZi' collect2: error: ld returned 1 exit status --- errorlevel 1 OK, maybe the cast is broken (well, to a pointer...), so changed this: surface = cast(T *)this.formula(); into this: T cls = cast(T)this; surface = cls.formula(); giving: dmd app.d app.o:(.data._D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSurface6__vtblZ+0x28): undefined reference to `_D3app31__T12ShapeSurfaceTC3app6SquareZ12ShapeSurface7formulaMFZi' collect2: error: ld returned 1 exit status --- errorlevel 1 So, if you could tell me: 1) Why the compiler defer to the linker 2) What is the CRTP equivalent here Many thanks. |
October 03, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to eles | On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:
> class ShapeSurface(T) {
> public:
> int formula();
that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is
class ShapeSurface(T) {
public:
abstract int formula();
|
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:
> On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:
>> class ShapeSurface(T) {
>> public:
>> int formula();
>
> that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is
>
> class ShapeSurface(T) {
> public:
> abstract int formula();
Thanks, but still. The compiler shall not let that code pass down to the linker. It has everything it needs to not do that, or it shall have. Linker errors shall be simply because the libraries are not in place (either not installed, either linking path not correctly configured, either broken versions of those libraries).
Then, a quirk of D:
this passes and works correctly:
surface = cast(T *)this.formula();
this segfaults the produced binary:
surface = (cast(T *)this).formula();
this fails:
surface = cast(T)this.formula();
with
app.d(8): Error: cannot cast this.formula() of type int to app.Square
while one has to throw in parentheses to make it work (correctly) once again:
surface = (cast(T)this).formula();
Isn't this funny, that you have to throw in parentheses depending on the type of the type you cast to?
|
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to eles | In the original you are casting an int to a pointer type, which is legitimate (although rarely a good idea). The other side of the matter is simply precedence. cast(T)a.b; Is really the same as: cast(T)(a.b); |
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | On Saturday, 4 October 2014 at 09:39:12 UTC, Chris Nicholson-Sauls wrote:
> In the original you are casting an int to a pointer type, which is legitimate (although rarely a good idea). The other side of the matter is simply precedence.
>
> cast(T)a.b;
>
> Is really the same as:
>
> cast(T)(a.b);
Yes, you are right. Then it's cast back when assigning.
|
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to eles | On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote:
> On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:
>> On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:
>>> class ShapeSurface(T) {
>>> public:
>>> int formula();
>>
>> that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is
>>
>> class ShapeSurface(T) {
>> public:
>> abstract int formula();
>
> Thanks, but still. The compiler shall not let that code pass down to the linker. It has everything it needs to not do that, or it shall have. Linker errors shall be simply because the libraries are not in place (either not installed, either linking path not correctly configured, either broken versions of those libraries).
Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.
// a.d
void foo();
void main() { foo(); }
// b.d
import std.stdio;
void foo() { writeln("Hello World"); }
$ ls
a.d b.d
$ dmd b.d -c
$ ls
a.d b.d b.o
$ dmd a.d b.o
$ ls
a a.d a.o b.d b.o
$ ./a
Hello World
So the compiler has no way of knowing whether you've forgotten to include a definition, or whether it's simply sitting in some other object file / library / whatever. The linker, however, can know, hence the linker error.
|
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Chris Nicholson-Sauls | On Saturday, 4 October 2014 at 09:39:12 UTC, Chris Nicholson-Sauls wrote:
> In the original you are casting an int to a pointer type, which is legitimate (although rarely a good idea). The other side of the matter is simply precedence.
>
> cast(T)a.b;
>
> Is really the same as:
>
> cast(T)(a.b);
But this also means that the cast is useless there, so there is no compile-time binding, so no CRTP.
Anyway, it ws just a game to write the equivalent.
|
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Saturday, 4 October 2014 at 10:27:18 UTC, John Colvin wrote: > On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote: >> On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote: >>> On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote: > So the compiler has no way of knowing whether you've forgotten to include a definition, or whether it's simply sitting in some other object file / library / whatever. The linker, however, can know, hence the linker error. No "extern" required?... |
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin Attachments: | On Sat, 04 Oct 2014 10:27:16 +0000 John Colvin via Digitalmars-d-learn <digitalmars-d-learn@puremagic.com> wrote: > Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration. is there any possibility to declare *class* *method* in one file and to implement it in another? O_O i doubt so. |
October 04, 2014 Re: Code fails with linker error. Why? | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Colvin | On Saturday, 4 October 2014 at 10:27:18 UTC, John Colvin wrote:
> On Saturday, 4 October 2014 at 04:02:46 UTC, eles wrote:
>> On Friday, 3 October 2014 at 15:47:33 UTC, John Colvin wrote:
>>> On Friday, 3 October 2014 at 15:44:16 UTC, eles wrote:
>>>> class ShapeSurface(T) {
>>>> public:
>>>> int formula();
>>>
>>> that means you have a definition of formula elsewhere (which the linker tries to find, but obviously fails. What you want is
>>>
>>> class ShapeSurface(T) {
>>> public:
>>> abstract int formula();
>>
>> Thanks, but still. The compiler shall not let that code pass down to the linker. It has everything it needs to not do that, or it shall have. Linker errors shall be simply because the libraries are not in place (either not installed, either linking path not correctly configured, either broken versions of those libraries).
>
> Sorry, but that's just not how it works. There is no requirement for the definition of a function to be found in the same compilation unit as it's declaration.
>
> // a.d
> void foo();
> void main() { foo(); }
>
> // b.d
> import std.stdio;
> void foo() { writeln("Hello World"); }
>
> $ ls
> a.d b.d
>
> $ dmd b.d -c
>
> $ ls
> a.d b.d b.o
>
> $ dmd a.d b.o
>
> $ ls
> a a.d a.o b.d b.o
>
> $ ./a
> Hello World
This seem to allow an entire class of problems, by linking against long-time forgotten functions...
|
Copyright © 1999-2021 by the D Language Foundation