相关疑难解决方法(0)

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

通过在这里工作,我认为std::atomic<T> a{}有效的零初始化a.我一直在这么想,并一直在使用它直到这个.在解释我对此的理解之前,我想表明,至少,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;
}
Run Code Online (Sandbox Code Playgroud)

输出0gccclang上.

以下是我解释为什么这应该起作用(当然,你可能会这样想).标准说

在以下操作定义中:

  • A指的是原子类型之一.

[...]

A::A() noexcept = default;
Run Code Online (Sandbox Code Playgroud)

效果:使原子对象处于未初始化状态.[注意:这些语义确保与C的兼容性. - 结束语]

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

如果T是一个类型,其默认构造函数既不是用户提供也不是删除(也就是说,它可能是一个具有隐式定义或默认默认构造函数的类),该对象是零初始化的,然后它是默认的 -如果它有一个非平凡的默认构造函数,则初始化;

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

  1. 零初始化然后
  2. 如果它具有非平凡的默认构造函数,则默认初始化.

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

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

8
推荐指数
1
解决办法
492
查看次数

是什么从形式上保证了非原子变量不会看到空气中的稀疏值,并且在理论上可以像原子弛豫一样创建数据竞争呢?

这是有关C ++标准的形式保证的问题。

该标准指出,std::memory_order_relaxed原子变量规则允许“凭空” /“出乎意料”的值出现。

但是对于非原子变量,这个例子可以有UB吗?是否r1 == r2 == 42有可能在C ++抽象机?== 42最初都不是变量,因此您不希望任何if主体执行,这意味着不会写入共享变量。

// Global state
int x = 0, y = 0;

// Thread 1:
r1 = x;
if (r1 == 42) y = r1;

// Thread 2:
r2 = y;
if (r2 == 42) x = 42;
Run Code Online (Sandbox Code Playgroud)

上面的示例改编自标准,该标准明确表示原子对象规范允许这种行为

[注意:在以下示例中,要求确实允许r1 == r2 == 42,而x和y最初为零:

// Thread 1:
r1 = x.load(memory_order_relaxed);
if (r1 == 42) y.store(r1, memory_order_relaxed);
// …
Run Code Online (Sandbox Code Playgroud)

c++ multithreading language-lawyer stdatomic data-race

3
推荐指数
3
解决办法
487
查看次数