Stock RHEL5 g++ 4.4 version: [Mon Mar 15 17:04:26] kenny:~/work$g++44 -v Using built-in specs. Target: i386-redhat-linux6E Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-languages=c,c++,fortran --disable-libgcj --with-mpfr=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-i386-redhat-linux6E/mpfr-install/ --with-ppl=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-i386-redhat-linux6E/ppl-install --with-cloog=/builddir/build/BUILD/gcc-4.4.0-20090514/obj-i386-redhat-linux6E/cloog-install --with-tune=generic --with-arch=i586 --build=i386-redhat-linux6E Thread model: posix gcc version 4.4.0 20090514 (Red Hat 4.4.0-6) (GCC)
Assume that there is a C++ shared library that uses STL extensively and is compiled with -fvisibility-ms-compat. Template member instantiations are however still visible: [Mon Mar 15 17:18:00] kenny:~/work$g++44 -c -fvisibility-ms-compat vis2.cc [Mon Mar 15 17:18:03] kenny:~/work$readelf -sW vis2.o | grep foo 153: 00000000 207 FUNC GLOBAL DEFAULT 72 _Z3foov ok, we want "foo" to be visible outside our shared library, but we do not want the following symbol to be visible: [Mon Mar 15 17:18:07] kenny:~/work$readelf -sW vis2.o | grep _M_range 179: 00000000 505 FUNC WEAK DEFAULT 121 _ZNSt5dequeIiSaIiEE19_M_range_initializeISt15_Deque_iteratorIiRiPiEEEvT_S7_St20forward_iterator_tag vis2.cc source code is: --- cut vis2.cc --- #include <deque> #define FOO_EXPORT __attribute__((visibility("default"))) int FOO_EXPORT foo() { std::deque<int> a; std::deque<int> b(a.begin(), a.end()); return 0; } --- cut vis2.cc --- This can be considered as an STL bug ("std" namespace is declared as having default visibility and thus all classes and all their members have default visibility) -- one may set "hidden" visibility on template member functions. But I think that at least -fvisibility-ms-compat should produce the code when template instantiations have hidden visibility, otherwise it will not be possible to be source-compatible with Visual Studio on this matter. I mean that the following source code (being an example of source compatibility with Visual Studio wrt. hidden visibility) will be compiled differently if used in shared library (or .DLL): --- cut foo.h --- #include <iostream> #if defined(_MSC_VER) #define FOO_EXPORT __declspec(dllexport) #define FOO_IMPORT __declspec(dllimport) #else #define FOO_EXPORT __attribute__((visibility("default"))) #define FOO_IMPORT __attribute__((visibility("default"))) #endif #if defined(_BUILD_FOO_DLL) #define FOO_API FOO_EXPORT #else #define FOO_API FOO_IMPORT #endif class FOO_API Foo { public: template<typename T> void foo(const T &t) { std::cout << t << std::endl; } }; --- cut foo.h --- Or there should be additional command line option that enables such behavior. -- Summary: template member function instantiations are not hidden if the class has default visibility and -fvisibility-ms- compat is used Product: gcc Version: unknown Status: UNCONFIRMED Severity: major Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: fjoe at samodelkin dot net http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43376