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
个对象是不够的。必须对操作进行排序。
我在 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 ofvolatile
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
个对象是不够的。必须对操作进行排序。