С++ 11 Глобальный порядок инициализации и thread_local

Привет, при выполнении следующего с использованием gcc 4.8.1 при использовании ключевого слова thread_local выполняется утверждение. При удалении thread_local утверждение не срабатывает. Кто-нибудь знает, почему это так? Существует некоторый неопределенный глобальный порядок, но я ожидаю, что buf_ будет иметь действительный адрес до назначения ptr_. Просто удалите ключевое слово thread_local, и это сработает для меня.

Выход:

$ ./ThreadLocal 
 Running Tester 
ThreadLocal: main.cpp:13: int main(): Assertion `buf == ptr' failed.
Aborted (core dumped)

Output when removing thread_local keyword
 Running Tester 

Тест.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 );
}

person bjackfly    schedule 24.10.2014    source источник


Ответы (1)


Похоже на ошибку в GCC. По-видимому, Tester::_mem вообще не инициализируется. GCC 4.9.0 делает то же самое, но clang 3.5.0 работает нормально

Если _mem не зависеть от параметра шаблона, вызывает сбой GCC.

Наконец, превращение Tester в нешаблонный класс наконец-то заставляет GCC работать.

Обновление: кажется, что они известны ошибки в GCC.

person Anton Savin    schedule 24.10.2014