https://gcc.gnu.org/bugzilla/show_bug.cgi?id=89088
Bug ID: 89088 Summary: Dllexport for explicit template instantiation missing inline methods Product: gcc Version: 8.2.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: martin at martin dot st Target Milestone: --- Created attachment 45538 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=45538&action=edit Sample code showing the issue With dllexported explicit template instantiation, inline methods aren't exported, but callers still create undefined references to the inline methods, which fail due to the missing export. (This can be remedied by applying -Wl,--export-all-symbols to export all generated symbols, regardless of dllexport attributes.) Example: header.h: template <class T> struct C { void f(); void g() {} }; template <class T> void C<T>::f() {} extern template class #ifdef DLLEXPORT __declspec(dllexport) #elif defined(DLLIMPORT) __declspec(dllimport) #endif C<char>; lib.cpp: #define DLLEXPORT #include "header.h" template class C<char>; caller.cpp: #define DLLIMPORT #include "header.h" int main(int argc, char* argv[]) { C<char> a; a.g(); return 0; } Building of this fails in this way: $ make x86_64-w64-mingw32-g++ -c -o caller.o caller.cpp x86_64-w64-mingw32-g++ -c -o lib.o lib.cpp x86_64-w64-mingw32-g++ -shared -o lib.dll lib.o -Wl,--out-implib,liblib.dll.a x86_64-w64-mingw32-g++ -o caller.exe caller.o -L. -llib caller.o:caller.cpp:(.text+0x1c): undefined reference to `C<char>::g()' collect2: error: ld returned 1 exit status Makefile:5: recipe for target 'caller.exe' failed make: *** [caller.exe] Error 1 The instantiation definition in lib.cpp emitted both methods, but only export the non-inline method: $ x86_64-w64-mingw32-nm lib.o <snip> 0000000000000000 T _ZN1CIcE1fEv 0000000000000000 T _ZN1CIcE1gEv $ x86_64-w64-mingw32-objdump -s lib.o <snip> Contents of section .drectve: 0000 202d6578 706f7274 3a225f5a 4e314349 -export:"_ZN1CI 0010 63453166 45762200 cE1fEv". However, despite this, the caller creates an undefined reference to the inline method: $ x86_64-w64-mingw32-nm caller.o <snip> 0000000000000000 T main U _ZN1CIcE1gEv