https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88292
Bug ID: 88292 Summary: Static initialization problem with thread_local and templates Product: gcc Version: 7.3.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: tobias.bruell at gmail dot com Target Milestone: --- I believe the following code should never print a null-pointer. Works as I expect with clang. Also, there are various ways in which it can be made work in gcc, including: * uncommenting the first commented line (and commenting the one before) * uncommenting the second commented line * removing the superfluous template parameter on context * removing all "thread_local" tokens May be duplicate, but I submit it anyway, in case you might find it helpful as an additional test. #include <iostream> template<typename T> struct store_ptr { static T *ptr () { return current_; } static thread_local T *current_; }; template<typename T> thread_local T * store_ptr<T>::current_ = [] { static thread_local T retval; return &retval; } (); template<typename T> struct context : public store_ptr<context<T>> { context () { } context (T) : previous_ {store_ptr<context<T>>::current_} // : previous_ {store_ptr<context<T>>::ptr ()} { store_ptr<context<T>>::current_ = this; } ~context () { store_ptr<context<T>>::current_ = this->previous_; } context<T> *previous_ = nullptr; }; int main () { //std::cout << context<int>::ptr () << '\n'; { context<int> ctx (1); std::cout << context<int>::ptr () << '\n'; } std::cout << context<int>::ptr () << '\n'; }