[Bug c++/38175] New: Explicit instantiation of a template hides symbols with the default visibility attribute

j dot s dot wijnhout at lumc dot nl gcc-bugzilla@gcc.gnu.org
Wed Nov 19 10:35:00 GMT 2008


The complete, though minimal, sample code will be attached to the bug report.
Since the problem only occurs when using multiple compilation units, the tar
contains multiple files. Note that the code is entirely self-contained. The tar
file contains a script BuildFail.sh that reproduces the error.

System info can be found at the bottom of the description.

I've tested using GCC 4.1.3,4.2.4,4.3.2 and the snapshot 4.4 20081114. 

The problem is related to using -fvisibility=hidden and explicit template
instantiation.

Consider two template classes:

template < typename _T > class TemplatedClass
{
public:
  TemplatedClass ();
};

template < typename _T > class DependentTemplatedClass
{
public:
  DependentTemplatedClass ();
  _T m_Member;
};

Suppose both are explicitly instantiated in separate compilation units (this is
essential!):
In one compilation unit do:
template class LIBRARY_EXPORT TemplatedClass < int >;

And in another:
template class LIBRARY_EXPORT DependentTemplatedClass < TemplatedClass < int >
>;

The macro LIBRARY_EXPORT, defined in Export.h, gives default visibility to the
instantiations. 

Note that in the second instantiation the template argument is precisely the
class that is instantiated in the first compilation unit.

Running the following commands:
g++ -DLIBRARY_EXPORTS -fvisibility=hidden -fPIC   -o LibraryInst1.cpp.o -c
LibraryInst1.cpp
g++ -DLIBRARY_EXPORTS -fvisibility=hidden -fPIC   -o LibraryInst2.cpp.o -c
LibraryInst2.cpp
g++ -fPIC  -fvisibility=hidden  -shared -Wl,-soname,libLibrary.so -o
libLibrary.so LibraryInst1.cpp.o LibraryInst2.cpp.o 
g++ -fvisibility=hidden  -o Application.cpp.o -c Application.cpp
g++ -fvisibility=hidden  -fPIC Application.cpp.o  -o Application -rdynamic
libLibrary.so

yields:
Application.cpp.o: In function `main':
Application.cpp:(.text+0x11): undefined reference to
`TemplatedClass<int>::TemplatedClass()'
collect2: ld returned 1 exit status

Upon closer inspection using:
nm -C libLibrary.so | grep Templated
000004f2 t TemplatedClass<int>::TemplatedClass()
000004ec W TemplatedClass<int>::TemplatedClass()
0000050c W DependentTemplatedClass<TemplatedClass<int>
>::DependentTemplatedClass()
000004f8 W DependentTemplatedClass<TemplatedClass<int>
>::DependentTemplatedClass()
it appears that the constructor of TemplatedClass<int> appears twice, but the
first instance is in the hidden .text section. Therefore the linker can't find
it.

I have found a workaround by defining the class using the LIBRARY_EXPORT macro:
template < typename _T > class LIBRARY_EXPORT TemplatedClass
{
public:
  TemplatedClass ();
};
However, such a solution makes it impossible to use a single macro to export
symbols using GCC and MSVC (I won't go into the details, but MSVC does not
accept a dllimport compiler directive when using "manual" instantiation). So
this workaround is not suitable for me.

The problem seems to be that the instantiation of
DependentTemplatedClass<TemplatedClass<int> > induces an instantiation of
TemplatedClass <int> (which is contained as a member. However, this time the
default visibility is not honored.

Here is some information about my system:

version used: snapshot gcc 4.4-20081114

commands to build the snapshot:
../../gcc-4.4-20081114/configure
--prefix=/home/wijnhout/Projects/gcc/install/4.4-20081114 --disable-libgcj
--enable-languages=c,c++
make
make -j4
make install

system info:
Intel(R) Core(TM)2 Quad CPU    Q6600  @ 2.40GHz

Ubuntu 8.10

$ uname -a
Linux 2-lkeb-mri-jwij 2.6.27-8-generic #1 SMP Thu Nov 6 17:33:54 UTC 2008 i686
GNU/Linux


-- 
           Summary: Explicit instantiation of a template hides symbols with
                    the default visibility attribute
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: j dot s dot wijnhout at lumc dot nl
 GCC build triplet: i686-pc-linux-gnu
  GCC host triplet: i686-pc-linux-gnu
GCC target triplet: i686-pc-linux-gnu


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=38175



More information about the Gcc-bugs mailing list