https://gcc.gnu.org/bugzilla/show_bug.cgi?id=62280
Bug ID: 62280 Summary: Symbols visibility not equivalent to class visibility (-fvisibility=hidden) Product: gcc Version: 4.9.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: mathieu.malaterre at gmail dot com I am trying to compile a project that is written in portable C++. It does compile fine with Visual Studio 2010 on Windows 7 and makes uses of symbol visibilty macros. However when I compile this project with gcc-4.7/gcc-4.9.1 on linux, I am getting this linker error: g++ -fvisibility=hidden -fvisibility-inlines-hidden [...] /tmp/ccegevbt.o:(.rodata._ZTI12subclass[_ZTI12subclass]+0x10): undefined reference to `typeinfo for ns::baseclass' I did read a [previous report][1] and indeed exporting at class level directly (instead of per symbol) solves the symptoms: class __attribute__ ((visibility ("default"))) baseclass { However the code is actually written to export only some member function, so it should produce identical behavior with Visual Studio C++ compiler, right ? class baseclass { public: // Member functions DLL_EXPORT baseclass(); DLL_EXPORT virtual ~baseclass(); My question: is what slightly different behavior in exporting symbols is happening in between Visual Studio 2010 and gcc-4.7 ? How do I track which symbol is actually causing issue ? For clarification here is a very small toy example which works fine on Visual Studio 2010 $ cat test.h #pragma once #ifdef __GNUC__ #define DLL_EXPORT __attribute__((visibility("default"))) #else #define DLL_EXPORT __declspec(dllexport) #endif struct Base { DLL_EXPORT virtual ~Base(); DLL_EXPORT virtual Base* clone() { return 0; } }; #undef DLL_EXPORT and $ cat test.cpp #include "test.h" Base::~Base() { } and $ cat main.cpp #include "test.h" struct Foo : public Base { virtual ~Foo(); virtual Base* clone() { return new Foo(); } }; Foo::~Foo() { } int main() { Base* f = new Foo(); f->clone(); return 0; } using cmake, it is simply: $ cat CMakeLists.txt cmake_minimum_required(VERSION 2.8) project(bla) add_library(test SHARED test.cpp) add_executable(main main.cpp) target_link_libraries(main test) >From linux: $ export CXXFLAGS="-fvisibility=hidden -fvisibility-inlines-hidden" $ cmake . && make >From windows: $ cmake . -G"NMake Makefiles" $ nmake For people not using cmake, you could use: $ cat Makefile main: main.cpp test.h libtest.so g++ -fvisibility=hidden -fvisibility-inlines-hidden -L. -ltest main.cpp -o main libtest.so: test.cpp test.h g++ -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -shared test.cpp -o libtest.so which leads to: $ make g++ -fvisibility=hidden -fvisibility-inlines-hidden -fPIC -shared test.cpp -o libtest.so g++ -fvisibility=hidden -fvisibility-inlines-hidden -L. -ltest main.cpp -o main /tmp/cc5lGsdn.o: In function `Base::Base()': main.cpp:(.text._ZN4BaseC2Ev[_ZN4BaseC5Ev]+0xf): undefined reference to `vtable for Base' /tmp/cc5lGsdn.o:(.rodata._ZTI3Foo[_ZTI3Foo]+0x10): undefined reference to `typeinfo for Base' collect2: error: ld returned 1 exit status make: *** [main] Error 1 In case this matter, adding `-fno-devirtualize` does not help (as per sug from [here][2]) Of course the obvious solution of changing: struct Base into struct DLL_EXPORT Base does solve the symptoms. ref: http://stackoverflow.com/questions/25522229/tracking-an-issue-with-fvisibility-hidden-that-triggers-a-undefined-reference-t