c++ - 值初始化是否适用于原子对象?

标签 c++ c++11 language-lawyer atomic value-initialization

在这里工作,我的意思是std::atomic<T> a{}有效地零初始化 a .我一直这么想并且一直在实际使用它直到this .在解释我对此的理解之前,我想表明,至少 gcc 和 clang 在实践中是这样做的。

#include <cstring>
#include <atomic>
#include <iostream>

int main() {
  using atomic = std::atomic<int>;  
  auto p = (atomic*)operator new(sizeof(atomic));
  std::memset(p, -1, sizeof(atomic));
  new(p) atomic{};
  std::cout << p->load() << std::endl;
}

输出是0在两个gccclang .

以下是我对为什么这应该起作用的解释(当然,您可能不这么认为)。标准说

In the following operation definitions:

  • an A refers to one of the atomic types.

[...]

A::A() noexcept = default;

Effects: leaves the atomic object in an uninitialized state. [ Note: These semantics ensure compatibility with C. — end note ]

它基本上是说默认构造函数是微不足道的,什么都不做。我对此没有意见,但我不明白这如何使值初始化不适用。根据cppref ,值初始化的影响包括(强调我的):

if T is a class type with a default constructor that is neither user-provided nor deleted (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and then it is default-initialized if it has a non-trivial default constructor;

std::atomic有一个默认的默认构造函数,所以对象是

  1. 零初始化然后
  2. 如果它有一个非平凡的默认构造函数,它就是默认初始化的。

第 2 点在这里不适用,因为默认的默认构造函数是微不足道的,但我没有看到任何使第 1 点无效的语句。我的理解正确还是我遗漏了什么?

最佳答案

最终,值初始化情况的症结在于 [dcl.init]/7 ,项目符号 1 和 2:

To value-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause [class]) with a user-provided constructor ([class.ctor]), then the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);
  • T is a (possibly cv-qualified) non-union class type without a user-provided constructor, then the object is zero-initialized and, if T's implicitly-declared default constructor is non-trivial, that constructor is called.
  • ...

应用上面两个项目符号中的哪一个取决于用户提供的 c'tor。我在对其他答案的评论中不记得的是 = default; 应用于它时的复杂性。如果我们看一下 [dcl.fct.def.default]/4 给出的定义(强调我的):

Explicitly-defaulted functions and implicitly-declared functions are collectively called defaulted functions, and the implementation shall provide implicit definitions for them ([class.ctor] [class.dtor], [class.copy]), which might mean defining them as deleted. A special member function is user-provided if it is user-declared and not explicitly defaulted or deleted on its first declaration. A user-provided explicitly-defaulted function (i.e., explicitly defaulted after its first declaration) is defined at the point where it is explicitly defaulted; if such a function is implicitly defined as deleted, the program is ill-formed. [ Note: Declaring a function as defaulted after its first declaration can provide efficient execution and concise definition while enabling a stable binary interface to an evolving code base. — end note ]

我们看到 atomic 的默认 c'tor 不是用户提供的,因为它被声明为默认,而不是被声明然后定义为默认。因此 [dcl.init]/7 的第二个项目符号是适用的,对象被零初始化,然后是(非)调用(普通默认)构造函数,它什么也不做。

关于c++ - 值初始化是否适用于原子对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49400942/

相关文章:

c++ - 如何使用 QDataStream 反序列化 int 的 Vector

c++ - 什么是 long long 类型?

javascript - 将多个变量从 COM 返回给 JavaScript

c++ - 无法使用复印功能

python - 为什么我的缓冲区输出被切碎了? C++套接字编程

c++ - 引用基类时是否需要命名空间

c++ - 轻松构建 Chromium 基础 (libchrome) 库

c++ mysql查询字符串用引号和变量解析

vb.net - 为什么 VB.NET 的 "missing return value"警告专门排除 "non-intrinsic value types"?

c++ - 为什么我的 SFINAE 表达式不再适用于 GCC 8.2?