www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template instantiation question

reply "Dmitri Makarov" <dmakarv gmail.com> writes:
I have three modules a.d, b.d, and c.d:

file a.d:```
module i.a;

import i.c, i.b;

final class A {
public:
   void foo() {
     a.transmogrify();
   }
   S!void a;
}
```
--------------
file b.d:```
module i.b;

import i.a, i.c;

class B {
public:
   S!void b;
}
```
--------------
file c.d:```
module i.c;

struct C {}

struct S(T) {
   C transmogrify() {
     return C();
   }
}
```
--------------
When these modules compiled separately, I assume, both a.o and 
b.o contain a definition of i.c.S!void.S.transmogrify() instance. 
Is this correct? If so, how is the symbol redefinition resolved 
when the three object files are linked into a single executable?
Mar 18 2015
parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/18/2015 11:03 AM, Dmitri Makarov wrote:

 When these modules compiled separately, I assume, both a.o and b.o
 contain a definition of i.c.S!void.S.transmogrify() instance.
That is very likely but I played with different three files for a while and failed to see that.
 how is the symbol redefinition resolved when the three object
 files are linked into a single executable?
There are different kinds of symbols. For example, the following command on a Linux console will show that template instances are weak symbols (it is not an error to have one or more weak symbols). $ nm b.o | grep transmogrify 0000000000000000 W _D1c8__T1CTvZ1C12transmogrifyMFNaNbNiNfZi 'man nm' tells us that W indicates a weak symbol: "W" "w" The symbol is a weak symbol that has not been specifically tagged as a weak object symbol. When a weak defined symbol is linked with a normal defined symbol, the normal defined symbol is used with no error. When a weak undefined symbol is linked and the symbol is not defined, the value of the symbol is determined in a system-specific manner without error. On some systems, uppercase indicates that a default value has been specified. Ali
Mar 18 2015
parent reply "Dmitri Makarov" <dmakarv gmail.com> writes:
On Wednesday, 18 March 2015 at 18:26:07 UTC, Ali Çehreli wrote:
 $ nm b.o | grep transmogrify
 0000000000000000 W _D1c8__T1CTvZ1C12transmogrifyMFNaNbNiNfZi
What compiler do you use? For me, neither a.o nor b.o contain transmogrify definition: $ dmd -c -Ix x/i/a.d $ nm a.o | grep trans U _D1i1c8__T1STvZ1S12transmogrifyMFNaNbNiNfZS1i1c1C $ dmd -c -Ix x/i/b.d $ nm b.o | grep trans $
Mar 18 2015
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
(My earlier response seems to be lost; trying one more time.)

On 03/18/2015 12:09 PM, Dmitri Makarov wrote:

 On Wednesday, 18 March 2015 at 18:26:07 UTC, Ali Çehreli wrote:
 $ nm b.o | grep transmogrify
 0000000000000000 W _D1c8__T1CTvZ1C12transmogrifyMFNaNbNiNfZi
What compiler do you use?
dmd git head. I used simpler files: // a.d module a; import c; import b; auto foo() { auto c = C!void(); return c.transmogrify(); } void main() { assert(.foo() == b.foo()); } // b.d module b; import c; auto foo() { auto c = C!void(); return c.transmogrify(); } // c.d module c; struct C(T) { int transmogrify() { return 42; } } Then I built the program like this: $ dmd a.d -c $ dmd b.d -c $ dmd c.d -c $ dmd a.o b.o c.o Ali
Mar 18 2015