template specialization instantiation problem

Nathan Sidwell nathan@cs.bris.ac.uk
Mon Jun 29 05:19:00 GMT 1998


Hi,
I'm having a problem with duplicate instantiations of template
specializations. I believe it is a bug in egcs. Let me explain the
problem.

I have a template class, let's call it Template<T>, and for some
particular T, I specialize a member function. Let's take that to be
Template<int>::func.
I drive the compiler with -fno-implicit-templates, and then explicitly
instantiate the particular templates that I need (as explained in
gcc.info-10). The difficulty I'm having, is that even without the
explicit instatiation of Template<int>, the compiler emits a definition
of Template<int>::func. When I explicitly instantiate Template<int>, in
a separate compilation, but effecitively using the same source file, I
get two definitions of Template<int>::func -- both are the same. Of
course the linker barfs at this.

What I would expect is that the specialization Template<int>::func is
only emitted when I explicitly instantiate Template<int>.

I'm using egcs 1.0.3a on a Sun Solaris 2.5.1.

Here is a source file
--begin foo.cc
// test template instantiations

void handle(char const *);

template<class T> class Template
{
public:
  T obj;

  void func();
};
        
template<> void Template<int>::func()
{
  handle("specialization of Template<int>::func()");
  return;
}
        
template<class T> void Template<T>::func()
{
  handle("non-specialized Template<T>::func()");
  return;
}
Template<float>
f;                                                                                               
Template<int> i;

#ifdef INSTANTIATE
template class Template<float>;
template class Template<int>;   
#endif
--end foo.cc

The #ifdef is to show what happens with and without an explicit
instantiation.

Here is the command sequence I used,
--begin command log
nathan@laie:9585>uname
-a                                                                      
SunOS laie 5.5.1 Generic sun4u sparc SUNW,Ultra-1

nathan@laie:9586>egcs++ -v -S -fno-implicit-templates
foo.cc                                   
Reading specs from
/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/specs
gcc version egcs-2.90.29 980515 (egcs-1.0.3 release)

/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/cpp
-lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus
-D__GNUC_MINOR__=90 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__sparc__
-D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix
-Asystem(unix) -Asystem(svr4) -D__EXCEPTIONS -D__GCC_NEW_VARARGS__
-Acpu(sparc) -Amachine(sparc) foo.cc /var/tmp/cca003Tx.ii
GNU CPP version egcs-2.90.29 980515 (egcs-1.0.3 release) (sparc)
#include "..." search starts here:
#include <...> search starts here:
 /home/staff/nathan/solaris/local/include/g++
 /usr/local/include
 /home/staff/nathan/solaris/local/SunOS_5/sparc-sun-solaris2.5.1/include

/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/include
 /usr/include
End of search list.

/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/cc1plus
/var/tmp/cca003Tx.ii -quiet -dumpbase foo.cc -version
-fno-implicit-templates -o foo.s
GNU C++ version egcs-2.90.29 980515 (egcs-1.0.3 release)
(sparc-sun-solaris2.5.1) compiled by GNU C version 2.6.3.

nathan@laie:9587>egcs++ -v -DINSTANTIATE -S -fno-implicit-templates
foo.cc -o foo-instantiate.s
Reading specs from
/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/specs
gcc version egcs-2.90.29 980515 (egcs-1.0.3 release)

/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/cpp
-lang-c++ -v -undef -D__GNUC__=2 -D__GNUG__=2 -D__cplusplus
-D__GNUC_MINOR__=90 -Dsparc -Dsun -Dunix -D__svr4__ -D__SVR4 -D__sparc__
-D__sun__ -D__unix__ -D__svr4__ -D__SVR4 -D__sparc -D__sun -D__unix
-Asystem(unix) -Asystem(svr4) -D__EXCEPTIONS -D__GCC_NEW_VARARGS__
-Acpu(sparc) -Amachine(sparc) -DINSTANTIATE foo.cc /var/tmp/cca003U0.ii
GNU CPP version egcs-2.90.29 980515 (egcs-1.0.3 release) (sparc)
#include "..." search starts here:
#include <...> search starts here:
 /home/staff/nathan/solaris/local/include/g++
 /usr/local/include
 /home/staff/nathan/solaris/local/SunOS_5/sparc-sun-solaris2.5.1/include

/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/include
 /usr/include
End of search list.

/home/staff/nathan/solaris/local/SunOS_5/lib/gcc-lib/sparc-sun-solaris2.5.1/egcs-2.90.29/cc1plus
/var/tmp/cca003U0.ii -quiet -dumpbase foo.cc -version
-fno-implicit-templates -o foo-instantiate.s
GNU C++ version egcs-2.90.29 980515 (egcs-1.0.3 release)
(sparc-sun-solaris2.5.1) compiled by GNU C version 2.6.3.
--end command log

both foo-noinstantiate.s and  foo-instantiate.s contain definitions of
func__t8Template1Zi.

I consider this a bug, because its presence makes the template
instantiation method 2 explained in gcc.info-10 around lines 946-986
unworkable in the presence of specializations. I lose the precise
control over where things are being instantiated which I thought I had
by using -fno-implicit-templates. I'm using the 'small files' method of
#including the .cc file which defines the template members, followed by
an explicit instantiation for the types I need. A shell script runs over
the source determining which instantiations are needed and then creates
the .cc files. The .cc file therefore gets compiled multiple times, once
without instantiations and once for each instantiation necessary.

nathan

-- 
Dr Nathan Sidwell :: Computer Science Department :: Bristol University
      You can up the bandwidth, but you can't up the speed of light      
nathan@acm.org  http://www.cs.bris.ac.uk/~nathan/  nathan@cs.bris.ac.uk



More information about the Gcc-bugs mailing list