零初始化的 std::atomic<T*> 保证等同于 nullptr 初始化的 std::T* 保证?

Is a zero initialized std::atomic<T*> guaranteed equivalent to one initialized with nullptr?

本文关键字:初始化 std 等同于 nullptr 保证 gt lt atomic      更新时间:2023-10-16

给定foo.cpp:

#include <atomic>
namespace {
    std::atomic<int*> gets_zero_init;
    std::atomic<int*> gets_nullptr{nullptr};
}

我相信gets_zero_init是零初始化的,并且它的初始化在零初始化之后完成。我也相信gets_nullptr最终会用nullptr初始化,我也相当相信gets_nullptr的初始化在零初始化后不会完成,因为std::is_trivially_constructible<decltype(gets_nullptr), int*>::valuefalse(至少,它在我的编译器上)。然而,我有点不清楚gets_nullptr是在常量初始化、静态初始化还是动态初始化之后完全初始化的。是哪一个?

此外,为了便于论证,我有兴趣确保感兴趣的对象在零初始化后完全初始化,并且不需要任何进一步的初始化,所以我采用gets_zero_init方法。由于零初始化,嵌入在gets_zero_init中的指针将保持全零位模式。

是否保证全零位模式等同于nullptr?换句话说,如果我想要gets_nullptr的语义,我可以依靠gets_zero_init的零初始化来提供吗?

我想我已经想通了。

首先,我的帖子有一个错误。我没有意识到零初始化和常量初始化只是静态初始化的不同形式。你得到一个或另一个,而不是一个然后另一个。所以,忽略这一点误解。

我相信gets_zero_initgets_nullptr都得到了静态初始化。第一个得到零初始化,有点明显。第二个得到恒定的初始化,因为:

  • 采用T的std::atomic构造函数是constexpr
  • gets_nullptr构造函数的自变量是一个常量表达式

换句话说,gets_zero_initgets_nullptr都有静态初始化,因此后一种是更好的选择,因为它不依赖于假设全零位模式等效于nullptr。