我正在使用__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不喜欢这样。