Re: Aliasing specialized template stuct in his module leads troubles

2013-03-02 Thread Rob T

On Saturday, 2 March 2013 at 03:59:59 UTC, H. S. Teoh wrote:

On Sat, Mar 02, 2013 at 04:17:10AM +0100, Rob T wrote:

In my case, the problem had to do with the order in which I was
linking my static libs, simply changing the order resolved the
undefined references. Turns out it's a common problem when 
working

with static libs and it's unrelated to D.

[...]

It's the linker's fault, not any compiler's. Symbols are 
resolved
according to the order of modules you specify on the 
command-line, so

order does matter, unfortunately.

IMNSHO this is a silly design -- in this day and age, one 
would've
expected better algorithms than that for linking -- but that's 
how it is

right now.


T


Maybe 20 years ago there was not enough cpu power to go around, 
but not anymore, so one would think this kind of problem could 
easily be resolved. It seems though, that most often dynamically 
loaded libs are used, not static, so perhaps the problems with 
static libs are due to it being not enough of a priority. 
Personally I prefer dynamically loaded libs and as soon as D 
supports it I'll be using them again almost exclusively.


--rt


Re: Aliasing specialized template stuct in his module leads troubles

2013-03-01 Thread H. S. Teoh
On Sat, Mar 02, 2013 at 04:17:10AM +0100, Rob T wrote:
> In my case, the problem had to do with the order in which I was
> linking my static libs, simply changing the order resolved the
> undefined references. Turns out it's a common problem when working
> with static libs and it's unrelated to D.
[...]

It's the linker's fault, not any compiler's. Symbols are resolved
according to the order of modules you specify on the command-line, so
order does matter, unfortunately.

IMNSHO this is a silly design -- in this day and age, one would've
expected better algorithms than that for linking -- but that's how it is
right now.


T

-- 
People say I'm indecisive, but I'm not sure about that. -- YHL, CONLANG


Re: Aliasing specialized template stuct in his module leads troubles

2013-03-01 Thread Rob T
In my case, the problem had to do with the order in which I was 
linking my static libs, simply changing the order resolved the 
undefined references. Turns out it's a common problem when 
working with static libs and it's unrelated to D.


--rt


Re: Aliasing specialized template stuct in his module leads troubles

2013-02-15 Thread Rob T

On Tuesday, 4 September 2012 at 22:46:00 UTC, Ivan Agafonov wrote:

I have my library module:

module mylib.vector;

// alias Vector!(float, 4) Vector4f;

struct Vector(T, uint size)
{
T[size] array = 0;
...
}


And I have client module:

import mylib.vector;

alias Vector!(float, 4) Vector4f;

void main()
{
auto x = Vector4f([1.0f, 2.0f, 3.0f, 4.0f]);
}


If alias would be in vector module (commented there) I will 
have to compile
both modules (otherwise I'll get link errors for some vector 
functions), but I want to simply import vector module and 
immediately use predefined aliases for vector template struct. 
How can I do this?



I've encountered the exact same problem.

I create an alias to define a specific type out of a template in 
the same library module that the template resides in. I can build 
the library OK, but when I build an executable and link in the 
library, the linker chokes out with an undefined symbol names.


If I comment out the alias, and instead define the same alias in 
each module where it is being used, I can rebuild my library and 
the executable OK.


This looks like a bug to me. The mystery is why almost no one is 
complaining about it, so it must be that just about nobody 
defines template aliases in this way.


I'll wait a while to see if there are any more comments before 
filing a bug report


--rt


Re: Aliasing specialized template stuct in his module leads troubles

2013-02-15 Thread Rob T
One more thing about this. If I leave in the alias in the same 
module where the template is defined, and also re-define the same 
alias in the other modules that make use out of it, the libraries 
will compile OK, but I'll get linking errors when I try to build 
an executable and link in the libs.


For each re-defined alias, I was able to confirm that the name 
mangling is identical in each module, so there's something going 
wrong specifically when the alias is defined in the same module 
where the template resides.


--rt



Re: Aliasing specialized template stuct in his module leads troubles

2012-09-04 Thread Ivan Agafonov

On Tuesday, 4 September 2012 at 23:51:49 UTC, bearophile wrote:

Ivan Agafonov:


(otherwise I'll get link errors for some vector functions),<


What errors and in what cases?



 Error 42: Symbol Undefined 
_D4time4math6vector16__T6VectorTfVi4Z6Vector8toStringMFZAya

hello.obj(hello)
 Error 42: Symbol Undefined 
_D4time4math6vector16__T6VectorTfVi4Z6Vector6__initZ

hello.obj(hello)
 Error 42: Symbol Undefined 
_D4time4math6vector16__T6VectorTfVi4Z6Vector6__ctorMFfZS4time4math6vector16__T6VectorTfVi4Z6Vector

hello.obj(hello)
 Error 42: Symbol Undefined 
_D4time4math6vector16__T6VectorTfVi4Z6Vector6__ctorMFG4fZS4time4math6vector16__T6VectorTfVi4Z6Vector


Re: Aliasing specialized template stuct in his module leads troubles

2012-09-04 Thread Ivan Agafonov

On Wednesday, 5 September 2012 at 01:49:50 UTC, Mike Parker wrote:

On 9/5/2012 7:46 AM, Ivan Agafonov wrote:

I have my library module:

module mylib.vector;

// alias Vector!(float, 4) Vector4f;

struct Vector(T, uint size)
{
T[size] array = 0;
...
}


And I have client module:

import mylib.vector;

alias Vector!(float, 4) Vector4f;

void main()
{
auto x = Vector4f([1.0f, 2.0f, 3.0f, 4.0f]);
}


If alias would be in vector module (commented there) I will 
have to compile
both modules (otherwise I'll get link errors for some vector 
functions),
but I want to simply import vector module and immediately use 
predefined

aliases for vector template struct. How can I do this?


If I understand your issue correctly, it isn't a "problem". 
It's the way D is designed to work. Simply importing a module 
does not mean that you do not also need to compile and link it 
in your program.


What importing does is make the symbols (declarations, 
definitions and so on) in the module available at compile time 
so that the compiler can know what is and isn't visible to the 
module it is currently compiling. But if there are any symbols 
in the imported module that need to be present at link time 
(such as variable declarations), then the imported module needs 
to be compiled and linked as well. In other words, it doesn't 
work like Java, where importing a class file causes the related 
class to be loaded a runtime.


Take the following example:

=
// foo.d
module foo;

struct Bar
{
int x;
}

// baz.d
module baz;

import foo;

void main()
{
Bar bar;
bar.x = 1;
}
=

You can compile this example like so:

dmd baz.d

And you wind up with a working program. The struct definition 
in foo.d is just a definition. The compiler uses it to know 
what is and isn't callable on Bar, how much memory an instance 
of it needs, and so on. So you can declare and instantiate 
instances of it in other modules without compiling and linking 
the foo module. Now let's change it up a bit:



// foo.d
module foo;

struct Bar
{
int x;
}

// Declare an instance of Bar here in the foo module
Bar foobar;

// baz.d
module baz;

import foo;

void main()
{
Bar bar;
bar.x = 1;

foobar.x = 2;
}


Now compile like so:

dmd baz.d

And this happens:


OPTLINK (R) for Win32  Release 8.00.12
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
baz.obj(baz)
 Error 42: Symbol Undefined _D3foo6foobarS3foo3Bar
--- errorlevel 1


The reason is because when the compile processes baz.d, it sees 
that it uses the variable foobar. That variable is not found in 
the baz module, but it is publicly visible in the foo module 
which baz imports. So the compiler says, ok, this is no 
problem. It goes about its job and creates baz.obj and passes 
it off to the linker. The linker looks through baz.obj, finds a 
reference to foobar, which, given the name mangling 
(_D3foo6foobarS3foo3Bar), should exist in an object file called 
foo (the linker knows nothing about D modules). So the linker 
wants to take foo.obj and link it together with bar.obj to 
create the final executable. Only, there is no foo.obj because 
you didn't compile it.


dmd baz.d foo.d

Now both object files can be created and linked together to 
make the final executable.


A template alias actually instantiates a template. A template 
instantiation must be available to the linker. So if you 
instantiate in the vector module, you *must* compile and link 
it. Generally, you should either pass all the modules you 
import along to the compiler, or link with a library in which 
those modules have been compiled. This way, you don't have to 
worry about what is declared or instantiated where.


Thank you, I anderstand this now. But this should not be true in 
some cases:

A template alias actually instantiates a template.
This only aliases, and if I create many specializations for 
future purposes, it should not instantiate each of them, sinse in 
code i can use any number of them, or not use at all. Real 
instantiation must be in the module, in which I use this aliases. 
I believe that this is the case, but with one factor - When I use 
this alias in main module compiller instantiatiates it in the 
module, in which it defined. I can't see the reasons by which 
compiller do so. Because if i put this aliases in main module or 
specialise in place (auto someVector = Vector!(float, 4)(0.5, 
...);) compiller will not do so. And I think there will take 
place only one instance for each specialisation in every module 
in which they are used. So in w

Re: Aliasing specialized template stuct in his module leads troubles

2012-09-04 Thread Mike Parker

On 9/5/2012 10:50 AM, Mike Parker wrote:




compiler says, ok, this is no problem. It goes about its job and creates
baz.obj and passes it off to the linker. The linker looks through
baz.obj, finds a reference to foobar, which, given the name mangling
(_D3foo6foobarS3foo3Bar), should exist in an object file called foo (the
linker knows nothing about D modules). So the linker wants to take
foo.obj and link it together with bar.obj to create the final
executable. Only, there is no foo.obj because you didn't compile it.


And, I should probably say, this isn't actually accurate. The linker 
knows nothing about D name mangling either. But the point is, if a 
symbol the linker needs isn't available in any of the object files you 
pass to it, it will complain.


Re: Aliasing specialized template stuct in his module leads troubles

2012-09-04 Thread Mike Parker

On 9/5/2012 7:46 AM, Ivan Agafonov wrote:

I have my library module:

module mylib.vector;

// alias Vector!(float, 4) Vector4f;

struct Vector(T, uint size)
{
 T[size] array = 0;
 ...
}


And I have client module:

import mylib.vector;

alias Vector!(float, 4) Vector4f;

void main()
{
 auto x = Vector4f([1.0f, 2.0f, 3.0f, 4.0f]);
}


If alias would be in vector module (commented there) I will have to compile
both modules (otherwise I'll get link errors for some vector functions),
but I want to simply import vector module and immediately use predefined
aliases for vector template struct. How can I do this?


If I understand your issue correctly, it isn't a "problem". It's the way 
D is designed to work. Simply importing a module does not mean that you 
do not also need to compile and link it in your program.


What importing does is make the symbols (declarations, definitions and 
so on) in the module available at compile time so that the compiler can 
know what is and isn't visible to the module it is currently compiling. 
But if there are any symbols in the imported module that need to be 
present at link time (such as variable declarations), then the imported 
module needs to be compiled and linked as well. In other words, it 
doesn't work like Java, where importing a class file causes the related 
class to be loaded a runtime.


Take the following example:

=
// foo.d
module foo;

struct Bar
{
int x;
}

// baz.d
module baz;

import foo;

void main()
{
Bar bar;
bar.x = 1;
}
=

You can compile this example like so:

dmd baz.d

And you wind up with a working program. The struct definition in foo.d 
is just a definition. The compiler uses it to know what is and isn't 
callable on Bar, how much memory an instance of it needs, and so on. So 
you can declare and instantiate instances of it in other modules without 
compiling and linking the foo module. Now let's change it up a bit:



// foo.d
module foo;

struct Bar
{
int x;
}

// Declare an instance of Bar here in the foo module
Bar foobar;

// baz.d
module baz;

import foo;

void main()
{
Bar bar;
bar.x = 1;

foobar.x = 2;
}


Now compile like so:

dmd baz.d

And this happens:


OPTLINK (R) for Win32  Release 8.00.12
Copyright (C) Digital Mars 1989-2010  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
baz.obj(baz)
 Error 42: Symbol Undefined _D3foo6foobarS3foo3Bar
--- errorlevel 1


The reason is because when the compile processes baz.d, it sees that it 
uses the variable foobar. That variable is not found in the baz module, 
but it is publicly visible in the foo module which baz imports. So the 
compiler says, ok, this is no problem. It goes about its job and creates 
baz.obj and passes it off to the linker. The linker looks through 
baz.obj, finds a reference to foobar, which, given the name mangling 
(_D3foo6foobarS3foo3Bar), should exist in an object file called foo (the 
linker knows nothing about D modules). So the linker wants to take 
foo.obj and link it together with bar.obj to create the final 
executable. Only, there is no foo.obj because you didn't compile it.


dmd baz.d foo.d

Now both object files can be created and linked together to make the 
final executable.


A template alias actually instantiates a template. A template 
instantiation must be available to the linker. So if you instantiate in 
the vector module, you *must* compile and link it. Generally, you should 
either pass all the modules you import along to the compiler, or link 
with a library in which those modules have been compiled. This way, you 
don't have to worry about what is declared or instantiated where.






Re: Aliasing specialized template stuct in his module leads troubles

2012-09-04 Thread bearophile

Ivan Agafonov:


(otherwise I'll get link errors for some vector functions),<


What errors and in what cases?

Bye,
bearophile


Aliasing specialized template stuct in his module leads troubles

2012-09-04 Thread Ivan Agafonov

I have my library module:

module mylib.vector;

// alias Vector!(float, 4) Vector4f;

struct Vector(T, uint size)
{
T[size] array = 0;
...
}


And I have client module:

import mylib.vector;

alias Vector!(float, 4) Vector4f;

void main()
{
auto x = Vector4f([1.0f, 2.0f, 3.0f, 4.0f]);
}


If alias would be in vector module (commented there) I will have 
to compile
both modules (otherwise I'll get link errors for some vector 
functions), but I want to simply import vector module and 
immediately use predefined aliases for vector template struct. 
How can I do this?