C ++ 11 Global initialization order and thread_local
Hi, when running the following use gcc 4.8.1 when using the thread_local keyword, the assertion is hit. When thread_local is removed, the assertion is not hit. Does anyone know why this is? There is some undefined global ordering, but I expect buf_ to have a valid address before assigning ptr_. Just remove the thread_local keyword and it works for me.
Output:
$ ./ThreadLocal
Running Tester
ThreadLocal: main.cpp:13: int main(): Assertion `buf == ptr' failed.
Aborted (core dumped)
Output when removing thread_local keyword
Running Tester
Test.hpp
#include <iostream>
#include <cassert>
template <typename std::size_t N>
struct Mem
{
Mem() noexcept: ptr_(buf_)
{}
char * getBuf() { return buf_; }
char * getPtr() { return ptr_; }
private:
char buf_[N];
char * ptr_;
};
template <typename std::size_t N>
struct Tester
{
Tester()
{
std::cout << " Running Tester " << std::endl;
}
char * getPtr() { return _mem.getPtr(); }
char * getBuf() { return _mem.getBuf(); }
private:
static thread_local Mem<N> _mem;
};
main.cpp
#include <iostream>
#include "Test.hpp"
template <typename std::size_t N>
thread_local Mem<N> Tester<N>::_mem;
int main()
{
Tester<500> t;
char * ptr = t.getPtr();
char * buf = t.getBuf();
assert( buf == ptr );
}
source to share
Seems like a bug in GCC. Apparently Tester::_mem
not initialized at all. GCC 4.9.0 does the same , but clang 3.5.0 works fine
Creation _mem
does not depend on the template parameter causes GCC to crash .
Finally, creating a Tester
class without a template makes GCC work last .
source to share