explicit instantiation of templates in g++ 4.0
>Submitter-Id: net
>Originator: Alan Rogers
>Organization: University of Utah
>Confidential: no
>Synopsis: Explicit instantiation of template has no effect.
>Severity: serious
>Priority: medium
>Category: c++
>Class: wrong-code
>Release: 4.0.1 (Debian 4.0.1-2) (Debian testing/unstable)
>Environment:
System: Linux dogwood 2.6.8-1-k7 #1 Thu Oct 7 02:47:47 EDT 2004 i686 GNU/Linux
Architecture: i686
host: i486-pc-linux-gnu
build: i486-pc-linux-gnu
target: i486-pc-linux-gnu
configured with: ../src/configure -v --enable-languages=c,c++,java,f95,objc,ada,treelang --prefix=/usr --enable-shared --with-system-zlib --libexecdir=/usr/lib --enable-nls --without-included-gettext --enable-threads=posix --program-suffix=-4.0 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --with-java-home=/usr/lib/jvm/java-1.4.2-gcj-4.0-1.4.2.0/jre --enable-mpfr --disable-werror --enable-checking=release i486-linux-gnu
>Description:
Here are three files that illustrate the problem.
Header file "t.hpp":
namespace arrpp {
template <typename B>
class A {
public:
A();
};
}
File implementing class A, called t.cc:
#include "t.hpp"
template class arrpp::A<char>; // instatiate class
template <typename B> arrpp::A<B>:: A(){} // define ctor
File containing main, called xt.cc:
#include "t.hpp"
int main(int argc, char **argv) { arrpp::A<char> x; }
Produce t.o and xt.o:
gcc -c t.cc xt.cc
Examine symbols in t.o:
nm t.o
(Produces no output, indicating that no symbols are defined.)
Try to link object files:
gcc -o xt xt.o t.o -lstdc++
xt.o: In function `main':
xt.cc:(.text+0x24): undefined reference to `arrpp::A<char>::A()'
collect2: ld returned 1 exit status
On a machine with g++-3.3, this code works fine (links and runs, producing no
output).
>How-To-Repeat:
See above. Here is the preprocessor output for t.cc:
# 1 "t.cc"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "t.cc"
# 1 "t.hpp" 1
namespace arrpp {
template <typename B>
class A {
public:
A();
};
}
# 2 "t.cc" 2
template class arrpp::A<char>;
template <typename B>
arrpp::A<B>::
A(){}
Here is the preprocessor output for xt.cc:
# 1 "xt.cc"
# 1 "<built-in>"
# 1 "<command line>"
# 1 "xt.cc"
# 1 "t.hpp" 1
namespace arrpp {
template <typename B>
class A {
public:
A();
};
}
# 2 "xt.cc" 2
int main(int argc, char **argv) {
arrpp::A<char> x;
}
>Fix:
Here is a patch for t.cc that provides a work-around. It instantiates
the class by declaring a variable:
--- t.cc 2005-10-01 10:53:33.038810604 -0600
+++ t2.cc 2005-10-01 10:53:47.335552612 -0600
@@ -1,6 +1,6 @@
#include "t.hpp"
-template class arrpp::A<char>;
+arrpp::A<char> foo;
template <typename B>
arrpp::A<B>::
Reply to: