带有模板的模板__thread初始化器

时间:2019-03-06 02:41:23

标签: c++ gcc clang thread-local-storage

我正在使用__thread和clang。

是的,我知道它不可携带。是的,我知道标准的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不喜欢这样。

0 个答案:

没有答案