Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Base template class symbols failing to link.

Reply
Thread Tools

Base template class symbols failing to link.

 
 
willo@cynd.net
Guest
Posts: n/a
 
      05-22-2009
All,

I'm having problems getting base-class template symbols to link
correctly.

My unit-test files are included below. I defined a templated Base-
Class 'A', and a templated Derived-Class 'B', only defining the
constructor and destructor.

I'm using 'g++-4.2', and get errors like:
willo:~/tmp$ g++ main.o B.o A.o -o main
B.o: In function `B<int>::B()':
B.cpp.text._ZN1BIiEC1Ev[B<int>::B()]+0x11): undefined reference to
`A<int>::A()'
B.o: In function `B<int>::~B()':
B.cpp.text._ZN1BIiED1Ev[B<int>::~B()]+0x11): undefined reference to
`A<int>::~A()'

This is despite the fact that I'm linking in another object file that
defines these symbols:
willo:~/tmp/$ nm --demangle A.o
0000000000000000 t instantiate_templated_class()
0000000000000000 W A<int>::A()
0000000000000000 W A<int>::~A()
U __gxx_personality_v0

Interestingly, if I remove the template parameter from Class A and B,
this error does not occur.

So, my question is, what am I doing wrong, or is what I'm trying to do
possible?

-- Charles Wilcox

willo:~/tmp$ cat A.h
#ifndef A_HEADER
#define A_HEADER

template< typename T >
class A
{
public: // methods
A();

~A();
};

#endif // ifndef A_HEADER

willo:~/tmp$ cat A.cpp
#include "A.h"

template< typename T >
A< T >::A() {}

template< typename T >
A< T >::~A() {}

static void instantiate_templated_class()
{
A< int > a;
}

willo:~/tmp$ cat B.h
#ifndef B_HEADER
#define B_HEADER

#include "A.h"

template< typename T >
class B : public A< T >
{
public: // methods
B();

~B();
};

#endif // ifndef B_HEADER

willo:~/tmp$ cat B.cpp
#include "B.h"

template< typename T >
B< T >::B() {}

template< typename T >
B< T >::~B() {}

static void instantiate_templated_class()
{
B< int > b;
}

willo:~/tmp$ cat main.cpp
#include "B.h"

int main( int argc, char* argv )
{
B< int > b;

return 0;
}
 
Reply With Quote
 
 
 
 
Leclerc
Guest
Posts: n/a
 
      05-22-2009
http://www.parashift.com/c++-faq-lite/templates.html

read about linking errors, separating templates into headers-sources,
and the rest of course
 
Reply With Quote
 
 
 
 
willo@cynd.net
Guest
Posts: n/a
 
      05-22-2009
On May 22, 1:17*am, Leclerc <gordan.sikic.rem...@this.inet.hr> wrote:
> http://www.parashift.com/c++-faq-lite/templates.html
>
> read about linking errors, separating templates into headers-sources,
> and the rest of course


Leclerc,

I've reviewed the Parashift info regarding templates and header / body
separation, and none of the information helps.

To re-iterate, I'm compiling each .cpp file just fine. I believe I've
separated the the .h and .cpp parts correctly.

This guide says nothing about linking templated base / derived
classes.

It's linking that has the problem. This is unexpected, as one of the
input compilation unit's defines the symbols that it complains about
not finding.

willo:~/tmp$ make
g++ -c -o main.o main.cpp
g++ -c -o B.o B.cpp
g++ -c -o A.o A.cpp
g++ main.o B.o A.o -o main
B.o: In function `B<int>::B()':
B.cpp.text._ZN1BIiEC1Ev[B<int>::B()]+0x11): undefined reference to
`A<int>::A()'
B.o: In function `B<int>::~B()':
B.cpp.text._ZN1BIiED1Ev[B<int>::~B()]+0x11): undefined reference to
`A<int>::~A()'
collect2: ld returned 1 exit status
make: *** [main] Error 1
willo:~/tmp/$ nm --demangle A.o
0000000000000000 t instantiate_templated_class()
0000000000000000 W A<int>::A()
0000000000000000 W A<int>::~A()
U __gxx_personality_v0
willo:~/tmp/$ nm --demangle B.o
0000000000000000 t instantiate_templated_class()
U A<int>::A()
U A<int>::~A()
0000000000000000 W B<int>::B()
0000000000000000 W B<int>::~B()
U __gxx_personality_v0

What is preventing the symbols for A in A.o from being used at link
time?

I could instantiate the A<int> symbols in B.o, but then I'd have
duplicate symbols, which can cause other linking errors in future
usage.

-- Charles Wilcox
 
Reply With Quote
 
Noah Roberts
Guest
Posts: n/a
 
      05-22-2009
wrote:
> On May 22, 1:17 am, Leclerc <gordan.sikic.rem...@this.inet.hr> wrote:
>> http://www.parashift.com/c++-faq-lite/templates.html
>>
>> read about linking errors, separating templates into headers-sources,
>> and the rest of course

>
> Leclerc,
>
> I've reviewed the Parashift info regarding templates and header / body
> separation, and none of the information helps.
>
> To re-iterate, I'm compiling each .cpp file just fine. I believe I've
> separated the the .h and .cpp parts correctly.


You haven't. You've not given the compiler the information it needs to
instantiate the template's functions in B.cpp and main.cpp. Move your
template's function definitions to the header file and get rid of both
A.cpp and B.cpp completely.
>
> This guide says nothing about linking templated base / derived
> classes.
>
> It's linking that has the problem. This is unexpected, as one of the
> input compilation unit's defines the symbols that it complains about
> not finding.


Of course it's linking that's the problem.

> I could instantiate the A<int> symbols in B.o, but then I'd have
> duplicate symbols, which can cause other linking errors in future
> usage.


B.o has no knowledge of there being an instantiation of A<int> anyway.
It's going to try to build its own and since you've not given it the
necessary knowledge to do so, it won't be able to.
 
Reply With Quote
 
willo@cynd.net
Guest
Posts: n/a
 
      05-22-2009
On May 22, 1:35*pm, blargg....@gishpuppy.com (blargg) wrote:
> willo wrote:
> > On May 22, 1:17=A0am, Leclerc <gordan.sikic.rem...@this.inet.hr> wrote:
> > >http://www.parashift.com/c++-faq-lite/templates.html

>
> > > read about linking errors, separating templates into headers-sources,
> > > and the rest of course

>
> > I've reviewed the Parashift info regarding templates and header / body
> > separation, and none of the information helps.

>
> > To re-iterate, I'm compiling each .cpp file just fine. *I believe I've
> > separated the the .h and .cpp parts correctly.

>
> Try re-reading questions 35.12 and 35.13, as they directly address your problem:
>
> http://www.parashift.com/c++-faq-lit...html#faq-35.12


I just got help from Marshall, and have resolved this.

Actually, section 35.13 has the answer, although the example is only
for a template-function.

In my posted sample-code, I used a static function
"instantiate_templated_class" per .cpp file to instantiate the
templated versions I wanted, specifically A< int > in A.cpp and B< int
> in B.cpp. I expected this to create the symbols needed in other

compilation-units.

However, that didn't work, and is not the way to do it. I should have
done:
template class A< int >
in A.cpp and:
template class B< int >
in B.cpp.

I had tried to do this before my posting, but I must have gotten the
syntax incorrect.

Anyway, thanks to all here and Marshall Cline for directing me to the
solution.

-- Charles Wilcox
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
base class public type (non template and template base class) Hicham Mouline C++ 1 04-20-2009 03:28 PM
r H2 deduce deduce template argument of a template class inheritingfrom a non template base? nguillot C++ 5 03-08-2009 05:56 PM
Non-template class from a template base class with pure virtual methods vilarneto@gmail.com C++ 2 03-25-2007 08:19 PM
Template specialisation of class with base class template ?! Tim Clacy C++ 12 12-03-2003 05:51 PM
Re: template class derived from non-template base class Matt Graham C++ 0 07-21-2003 09:02 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57