Tho*_*ell 44 c++ atomic stdstring stdatomic
我正在阅读Anthony Williams的"行动中的C++并发"和第5章,其中讨论了新的多线程感知内存模型和原子操作,并指出:
为了
std::atomic<UDT>用于某些用户定义的UDT类型,此类型必须具有普通的复制赋值运算符.
据我了解,这意味着std::atomic<UDT>如果以下内容返回true ,我们可以使用:
std::is_trivially_copyable<UDT>::value
Run Code Online (Sandbox Code Playgroud)
通过这种逻辑,我们不应该使用它std::string作为模板参数std::atomic并使其正常工作.
但是,以下代码使用预期输出进行编译和运行:
#include <atomic>
#include <thread>
#include <iostream>
#include <string>
int main()
{
std::atomic<std::string> atomicString;
atomicString.store( "TestString1" );
std::cout << atomicString.load() << std::endl;
atomicString.store( "TestString2" );
std::cout << atomicString.load() << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这是一个未定义的行为,恰好按预期行事吗?
提前致谢!
Cas*_*sey 45
该标准未指定专业化std::atomic<std::string>,因此通用template <typename T> std::atomic<T>适用.29.5 [atomics.types.generic] p1状态:
有一个泛型类模板atomic.模板参数T的类型应该是可以轻易复制的(3.9).
没有声明实施必须诊断违反此要求的行为.因此,(a)您使用std::atomic<std::string>调用未定义的行为,或(b)您的实现提供std::atomic<std::string>符合标准的扩展.
查看std::atomic<T>(http://msdn.microsoft.com/en-us/library/vstudio/hh874651.aspx)的MSDN页面,它明确提到了T可以轻易复制的要求,并且没有说明具体的内容std::atomic<std::string>.如果是扩展名,则没有记录.我的钱是未定义的行为.
具体来说,17.6.4.8/1适用(感谢DanielKrügler让我直截了当):
在某些情况下(替换函数,处理函数,用于实例化标准库模板组件的类型的操作),C++标准库依赖于C++程序提供的组件.如果这些组件不符合要求,则标准对实施没有要求.
std::string当然不符合std::atomic<T>模板参数T可以轻易复制的要求,因此标准对实现没有要求.作为执行质量问题,请注意,这static_assert(std::is_trivially_copyable<T>::value, "std::atomic<T> requires T to be trivially copyable");是一种容易诊断以捕获此违规行为.
2016-04-19更新:我不知道改变何时发生,但VS2015 Update 2现在确诊std::atomic<std::string>:
error C2338: atomic requires T to be trivially copyable.
小智 8
不,这是未定义的行为.此外,由于std :: string不是易于复制的,因此符合标准的编译器应该发出"至少一条诊断消息":
29.5原子类型
有一个泛型类模板atomic.模板参数T的类型应该是可以轻易复制的(3.9).
1.4实施合规
- 如果程序包含违反任何可诊断规则的情况,则符合要求的实施方案应至少发出一条诊断消息.