I am working on a fairly significantly-sized project which spans many shared libraries. We also have significant reliance on the STL, Boost and our own template classes and functions. Many exported classes contain template members and exported functions contain template parameters.
Here is a stripped-down example of how I do library exporting:
#if defined(_MSC_VER) && defined(_DLL)
// Microsoft
#define EXPORT __declspec(dllexport)
#define IMPORT __declspec(dllimport)
#elif defined(_GCC)
// GCC
#define EXPORT __attribute__((visibility("default")))
#define IMPORT
#else
// do nothing and hope for the best at link time
#define EXPORT
#define IMPORT
#endif
#ifdef _CORE_COMPILATION
#define PUBLIC_CORE EXPORT
#define EXTERNAL_CORE
#else
#define PUBLIC_CORE IMPORT
#define EXTERNAL_CORE extern
#endif
#include <deque>
// force exporting of templates
EXTERNAL_CORE template class PUBLIC_CORE std::allocator<int>;
EXTERNAL_CORE template class PUBLIC_CORE std::deque<int, std::allocator<int> >;
class PUBLIC_CORE MyObject
{
private:
std::deque<int> m_deque;
};
SO, my problem is that when I compile in Visual Studio (both 2008 and 2010), I get the following warning:
warning C4251: 'std::_Deque_val<_Ty,_Alloc>::_Almap' : class 'std::allocator<_Ty>' needs to have dll-interface to be used by clients of class 'std::_Deque_val<_Ty,_Alloc>'
Which seems to imply that I haven't exported std::allocator<int>
, which I have. And it's not like my exporting is incorrect, since not including
EXTERNAL_CORE template class PUBLIC_CORE std::allocator<int>;
EXTERNAL_CORE template class PUBLIC_CORE std::deque<int, std::allocator<int> >;
yields the warning:
warning C4251: 'MyObject::m_deque' : class 'std::deque<_Ty>' needs to have dll-interface to be used by clients of class 'MyObject'
The only thing I can think of is that the _Ty
the warning about the std::allocator
is talking about is somehow not int
, but I can't seem to find any indication that it would be otherwise, since a std::deque<int>
would logically allocate with an std::allocator<int>
.
A consuming application can use the class just fine, but I have a gut feeling that this warning should not be ignored. When compiling with g++ in Linux, no errors are emitted (although that doesn't mean it's working right). Is g++ automatically doing something that MSVC cannot do? I've been targeting GCC on Linux, LLVM on OSX and MSVC on Windows, but I could potentially move to MinGW for Windows development, so abandoning MSVC is not exactly out of the question (if this proves to be too big of an inconvenience).