Я использую __thread
с лязгом.
Да, я знаю, это непереносимо.Да, я знаю стандартное ключевое слово C ++ thread_local
.Я знаю о различиях.В этом случае я намеренно использую __thread
.
. Теперь и с Clang, и с G ++ ключевое слово __thread
может использоваться только с типами POD, которые имеют тривиальные деструкторы.
Дляпример:
struct Foo {};
__thread Foo f;
Однако кажется, что Clang запрещает использование __thread
, когда тип зависит от параметра шаблона - даже если сам шаблон никогда не создается (и, следовательно, Clang не имеет возможности дажепока скажите, является ли тип POD с тривиальным деструктором.)
Например, с GCC 4.9.2, я могу сказать:
template <class T>
struct Bar { T data; };
template <class T>
struct Foo
{
static __thread Bar<T> value;
};
template <class T>
__thread Bar<T> Foo<T>::value {};
Foo<int> f;
Это компилируется и работает нормально.
Но в Clang 4.0 точно такой же код говорит:
error: initializer for thread-local variable must be a constant expression
__thread Bar<T> Foo<T>::value {};
Даже если я удаляю строку Foo<int> f
, так что сам шаблон никогда не создается даже, Clang по-прежнему выдает ошибку.
Похоже, Clang просто не поддерживает это.Это где-нибудь задокументировано, или это просто ошибка в Clang?Единственная документация для __thread
с Clang, которую я могу найти, указывает, что она должна работать с любым типом POD.Но здесь Clang не проверяет, является ли тип POD или нет, поскольку он допускает ошибки еще до того, как будет создан экземпляр шаблона.
Так это ошибка в Clang?Есть какой-нибудь известный обходной путь?
РЕДАКТИРОВАТЬ: Я могу заставить его работать в Clang, если я удалю инициализатор {}
, например:
template <class T>
__thread Bar<T> Foo<T>::value;
Это может быть возможным обходным путем, но я не уверен, безопасно ли это.Я хочу убедиться, что локальное значение потока инициализируется нулями.Кажется, в документации не указано, является ли объект с __thread
хранилищем обязательно инициализированным нулями.Я думаю, что это будет, если это static
, но я бы предпочел явно указать инициализатор.К сожалению, Clang это не нравится.