I want to use the C++11 keyword thread_local in our Open Source library, which can be dynamically or statically linked on numerous platforms (Windows, Linux, Mac OS, ...), in the context of a static variable. This variable is of a class-type that basically just encapsulates a std::stringstream variable and initialises it to fit our stringstream formatting requirements. We want to have this statically available for performance reasons( see my previous question for more details) and it is okay if this is done per thread.
The global variable should be used in a static templated class methods, which have to be implemented in a header. But this means, if I understand correctly, that a user of the library may include this header in their executable's code, which would compile the templated methods into the executable. These methods would then access the mentioned global variable from within the executable's thread. How do i need to declare/define the static variable for this to work, i.e. do I need to export the variable or the class type or is it enough to declare it "static thread_local X"? This is my current declaration:
// SharedStringstream.h
#include <sstream>
// Export stands for _declspec(dllimport) or (dllexport) respectively
class EXPORT SharedStringstream
{
public:
SharedStringstream();
static thread_local SharedStringstream s_sharedStreamInstance;
std::stringstream d_sharedStream;
};
and the definition:
// SharedStringstream.cpp
#include "SharedStringStream.h"
SharedStringstream SharedStringstream::s_sharedStreamInstance();
SharedStringstream::SharedStringstream()
{
d_sharedStream.imbue(std::locale("C"));
d_sharedStream << std::skipws;
d_sharedStream >> std::skipws;
}
Without export i get linker errors, with it I get the following error in Visual Studio 2015:
Error C2492 'public: static SharedStringstream SharedStringstream::s_sharedStreamInstance': data with thread storage duration may not have dll interface
More info is given here which basically states that a thread_local
variable may not be exported. I would have to move it out of the class into my namespace for this purpose, is this the only way?
Furthermore:
The MSDN page on "Thread Local Storage" says the following in regard to thread_local
and DLLs:
The use of the thread attribute may interfere with delay loading of DLL imports.
We do internally use delay-loading of DLLs for some plugins that our library consists of, but there will not be any calls to the variable. I assume users could, however, delay-load the library, although we do not officially support this. Assuming we do not support delay-loading of our library and do not call the variable from any delay-loaded dlls internally, are we able to be sure this will not be an issue in any context?
Are there any issues I have not considered in my question?