[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: template instantiation g++ 4.0x

From: Tom H
Subject: Re: template instantiation g++ 4.0x
Date: Tue, 21 Mar 2006 11:00:43 -0700
User-agent: Thunderbird 1.5 (Windows/20051201)

Paul Pluzhnikov wrote:
Tom Hilinski <> writes:

I'm unable to get template code that builds with g++ 3.4.x to link
successfully in g++ 4.0.x
What you are doing is non-portable: when the instantion requests below
are seen by g++, it has not seen the body of ATemplate<T>::GetValue()
yet, and therefore can't actually instantiate anything.

template class ATemplate<int>;
template class ATemplate<float>;

Here is a fix:

  $ cat ATemplate.cpp
  #include "ATemplate.h"
  template <class T> T ATemplate<T>::GetValue () const { return n; }
  template class ATemplate<int>;
  template class ATemplate<float>;

Your ATemplateInst.h serves no apparent purpose anyway.


Thanks for your quick reply. My understanding of how g++ handles template instantiation in 3.4 agrees with the code example. From the manual (for both 3.4 and 4.0),the default compiler action is:

"...the compiler emits template instances in each translation unit that uses them, and the linker collapses them together."

So, ATemplate.cpp will have int and float versions of member GetValue. The header file ATemplateInst.h (which mimics the real system even if it isn't needed in this example) forces the instantiations. The linker (or collect2) should find the GetValue instances in ATemplate.o. This is what version 3.4 does, and 4.0 does not.

Looking at the symbols in the .o files shows that 4.0 is not generating instances of GetValue:

   nm -C ATemplate.o

g++ 3.3:

00000000 W ATemplate<float>::ATemplate[in-charge]()
00000000 W ATemplate<float>::ATemplate[not-in-charge]()
00000000 W ATemplate<int>::ATemplate[in-charge]()
00000000 W ATemplate<int>::ATemplate[not-in-charge]()
00000000 W ATemplate<float>::GetValue() const
00000000 W ATemplate<int>::GetValue() const

g++ 4.0:

0000000000000000 W ATemplate<float>::ATemplate()
0000000000000000 W ATemplate<float>::ATemplate()
0000000000000000 W ATemplate<int>::ATemplate()
0000000000000000 W ATemplate<int>::ATemplate()
                 U __gxx_personality_v0

Clearly the behavior of 4.0 in regards to template instantiation has changed from version 3.4.x. So which version is "correct"? Is it possible to force 4.0 to revert its actions to that of 3.4?


reply via email to

[Prev in Thread] Current Thread [Next in Thread]