我发现在实践中,对于各种C ++ 11 / C ++ 14编译器,std::atomic
具有未定义的初始值,就像它是“原始”类型一样。也就是说,我们希望表达式
int a;
a
可能有任何价值。对于表达式
std::atomic< int > b;
b
也可能有任何价值。换句话说,
std::atomic< int > b; // b is undefined
不等于
std::atomic< int > b{ 0 }; // b == 0
或
std::atomic< int > b{}; // b == 0
因为后两种情况b
被初始化为已知值。
我的问题很简单:C ++ 11或C ++ 14规范中记录了这种行为?
答案 0 :(得分:10)
[atomics.types.generic] / 5说这是关于整体专业化的:
原子积分专业化和专业化原子应具有标准布局。它们每个都有一个普通的默认构造函数和一个简单的析构函数。他们应各自支持聚合 初始化语法。
此外,同一节开头的主要模板概要规范性地将默认构造函数指定为:
atomic() noexcept = default;
效果在[atomic.types.operations] / 4中定义为:
效果:使原子对象处于未初始化状态。
答案 1 :(得分:6)
§29.6.5[atomics.types.operations.req] N 4140中的第4节(C ++ 14的最终草案)说:
A ::A () noexcept = default;
效果:使原子对象处于未初始化状态。 [注意:这些语义确保与C的兼容性。 - 结束注释]
请注意,这并不意味着对象包装了您可以读取但未依赖其值的未指定值。相反,它意味着在分配对象之前从对象中读取值会导致未定义的行为。