C++:为什么易失性访问需要排序?

C++: Why does volatile access needs sequencing?

我在 C++ 测验网站上浏览了下面的代码。它还提供了解释。我知道 volatile 限定符向编译器发出信号,表明变量的值可能会被其他一些因素改变。该站点的解释补充说访问 volatile 应该按顺序进行。为什么以及如何对其进行排序?

我不明白未排序的副作用标量对象是什么意思。也请说清楚。

#include <iostream>
volatile int a;
int main() {
  std::cout << (a + a);
}

The issue here is not the missing initializer of the variable a - it will implicitly be initialized to 0 here. But the issue is the access to a twice without sequencing between the accesses. According to §1.9¶12, accesses of volatile glvalues are side-effects and according to §1.9¶15 these two unsequenced side-effects on the same scalar object result in undefined behavior.

这里没有定义这两个访问中哪个先发生。

在这种情况下,对称加法运算无关紧要。

但考虑一个不对称的不同操作:

std::cout << a * (a+1);

现在,考虑一个 volatile 对象,由于外部因素,它在每次访问后自动递增。例如,假设 a 是某种硬件寄存器。正如我所说,假设每次访问它时它都会递增,因此硬件寄存器在第一次访问时包含值 4,在第二次访问时包含值 5。一个简单的计数器。

那么,如果第一次访问是乘法左边,第二次访问是乘法右边的加法运算,那么就变成了

std::cout << 4 * (5+1);

但是如果第一次访问是右手边,第二次访问是左手边,这就变成了

std::cout << 5 * (4+1);

这就是为什么只有 volatile 个对象是不够的。必须对操作进行排序。