C++:为什么volatile访问需要排序

C++: Why does volatile access needs sequencing?

本文关键字:排序 访问 volatile 为什么 C++      更新时间:2023-10-16

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

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

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

这里的问题不是缺少变量a的初始值设定项,而是将在此处隐式初始化为0。但问题是访问到a两次,而不在访问之间排序。根据§1.9¶12,volatileglvalues的访问是副作用,根据到§1.9¶15这两个未排序的副作用在同一标量上对象导致未定义的行为。

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

在这种对称加法运算的情况下,这并不重要。

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

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

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

然后,如果第一次访问用于乘法的左手侧,而第二次访问用于对乘法的右手侧访问的加法运算,则这变为

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

但是,如果第一次访问是针对右手侧,而第二次访问则是针对左手侧,则这将成为

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

这就是为什么仅仅拥有volatile对象是不够的。操作必须按顺序进行。