考虑:
void foo() {
std::vector<std::atomic<int>> foo(10);
...
}
Run Code Online (Sandbox Code Playgroud)
foo的内容现在有效吗?还是我需要显式循环并初始化它们?我检查了Godbolt,它看起来还不错,但是在这一点上,标准似乎非常混乱。
所述的std ::矢量构造器表示,它插入默认插入的实例std::atomic<int>,这是初始化值经由放置new。
我认为这种价值初始化的效果适用:
2)如果T是具有既不由用户提供也未删除的默认构造函数的类类型(即,它可能是具有隐式定义或默认默认构造函数的类),则将该对象初始化为零,然后将其如果具有非平凡的默认构造函数,则默认初始化;
因此在我看来,原子是零初始化的。所以问题是,是否std::atomic<int>在有效对象中对结果进行零初始化?
我猜答案是“在实践中是,但没有真正定义”?
注意:此答案同意它是零初始化的,但并没有真正说明是否意味着该对象有效。
考虑一下代码:
#include <atomic>
#include <iostream>
struct stru {
int a{};
int b{};
};
int main() {
std::atomic<stru> as;
auto s = as.load();
std::cout << s.a << ' ' << s.b << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
请注意,尽管stru具有默认成员初始值设定项,但它仍然符合自C++ 14以来的聚合类型.std::atomic有一个普通的默认构造函数.根据标准,成员as应该初始化为零吗?clang 6.0.0不会这样做(见这里),而gcc 7.2.0似乎是这样(见这里).
由于今天是美国的感恩节,所以我将被指定为土耳其来问这个问题:
Take something as innocuous as this. An atomic with a simple plain old data type such as an int:
atomic<int> x;
cout << x;
Run Code Online (Sandbox Code Playgroud)
The above will print out garbage (undefined) data. Which makes sense given what I read for the atomic constuctor:
(1) default constructor
Leaves the atomic object in an uninitialized state. An uninitialized atomic object may later be initialized by calling atomic_init.
Feels like an odd committee decision. But I'm sure they had their reasons. …
考虑以下两行代码:
std::atomic_flag a { }; // Since C++20
std::atomic_flag a = ATOMIC_FLAG_INIT; // Until C++20
Run Code Online (Sandbox Code Playgroud)
在 C++20 中,第一行初始化a为清除状态,但如果我在 C++17 中使用它,a将初始化为未指定的状态。第二行在 C++20 中已弃用,但在 C++ 17 中,它初始化a为清除状态。我怎样才能将它们都包含在代码中?我想我应该使用宏,但是那个宏到底是什么?它适用于所有其他类型的初始化吗std::atomic<T>?