My use case is as follows. I have a class template `S` with implicit inline functions in `lib.h`. To improve compilation times, I want to explicitly instantiate common specializations of this class template in `lib.cpp`. In order to do so, I want to provide an explicit instantiation declaration (`extern template`) of `S<int>` in `lib.h`, and an explicit instantiation definition of `S<int>` in `lib.cpp`. Now, I expect that every consumer linking against `lib` should be able to use `S<int>` without having to fully instantiate it.
The example I provided in my bug report cleanly compiles and links with clang++, regardless of whether I have `__declspec(dllexport)` or not in the declaration. The example does not link when compiling `lib` with g++, if I have `__declspec(dllexport)` in the declaration. It does link if I enable `-Wl,--export-all-symbols` or if I remove the `__declspec(dllexport)` altogether. Putting the `__declspec(dllexport)` on the explicit template instantiation definition results in a compiler warning telling me that it is ignored. These results make me believe that we are experiencing a g++ bug related to symbol exporting when targeting MinGW. In my real project (see https://github.com/vittorioromeo/SFML/tree/feature/remove_windows_h_dependency_for_gl_h, Vector2 class), where I have the same use case, there's nothing I can do. Regardless of whether I have `__declspec(dllexport)` or not, I get linker errors on the explicit template instantation for `constexpr` member functions such as `sf::Vector2<unsigned int>::Vector2()`, which are declared and defined as follows: // // ---------------------------------------------------------------------------- // Vector2.hpp (sfml-system library) namespace sf { template <typename T> class Vector2 { public: SFML_SYSTEM_API constexpr Vector2(); // ... }; } extern template sf::Vector2<unsigned int>::Vector2(); template <typename T> constexpr sf::Vector2<T>::Vector2() = default; // // ---------------------------------------------------------------------------- // Vector2.cpp (sfml-system library) template sf::Vector2<unsigned int>::Vector2(); // // ---------------------------------------------------------------------------- // GlContext.cpp (sfml-window library, depends on sfml-system) // ... std::make_unique<ContextType>(/* ... */, Vector2<unsigned int>(1, 1)); // ^^^^^^^^^^^^^^^^^^^^^^^^^^^ // linker error here with g++ // ... Removing `SFML_SYSTEM_API` or adding it to the explicit template definition has no effect at all. Removing the `extern template` results in another GCC bug, see (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109387). Therefore I see no possible solution to my problem. Hope this helps -- cheers, Vittorio Romeo https://vittorioromeo.com ________________________________ From: LIU Hao Sent: Monday, April 03, 2023 12:04 PM To: mingw-w64-public@lists.sourceforge.net; Vittorio Romeo Subject: Re: [Mingw-w64-public] GCC bugs with explicit template instantiation and dllexport targeting MinGW 在 2023/4/3 16:55, Vittorio Romeo 写道: > Hello everyone, > Hope you are doing well. > > I've encountered and reported a bug related to explicit template > instantiations and dllexport using the latest version of GCC on MinGW/MSYS2: > https://gcc.gnu.org/bugzilla/show_bug.cgi?id=109380 I don't think it's a bug. There are two issues in your testcase, one is that extern template struct __declspec(dllexport) S<int>; is a declaration, and nothing can be exported from a declaration (you export the definition instead). The other is that `g()` is an implicit inline function. An inline function can only be exported when it is emitted as a non-inline copy, for example, when optimization is not enabled, or when its address is taken, or when it is virtual and the class has a non-pure non-inline virtual function (a.k.a. the key function) which instantiates its vtable. -- Best regards, LIU Hao _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public