我在C ++测验网站上查看了下面的代码。它还提供了解释。我知道volatile
限定符向编译器发出信号,表明变量的值可能会被其他一些因素改变。该网站的解释补充说,应该对访问volatile
进行排序。为什么以及如何排序?
我不明白无序序副作用和标量对象的含义。还请说清楚。
#include <iostream>
volatile int a;
int main() {
std::cout << (a + a);
}
这里的问题不是缺少变量
a
的初始值设定项 - 它 这里将隐式初始化为0。但问题是访问权限 在访问之间没有排序的两次。根据 §1.9¶12,volatile
glvalues的访问是副作用和依据 §1.9¶15对同一标量的这两个未测序的副作用 对象导致未定义的行为。
答案 0 :(得分:6)
此处未定义两个访问中的哪一个首先出现。
在这种对称加法运算的情况下,它并不重要。
但考虑一个不对称的不同操作:
std::cout << a * (a+1);
现在,考虑一个volatile
对象,由于外部因素,每次访问后都会自动递增。让我们说,例如,a
是某种硬件寄存器。正如我所说,让我们说每次访问它都会增加,因此硬件寄存器在第一次访问时包含值4,在第二次访问时包含5。一个简单的柜台。
然后,如果第一次访问是乘法的左侧,第二次访问是乘法右侧访问的加法运算,那么这就成了
std::cout << 4 * (5+1);
但是,如果第一次访问是针对右侧,第二次访问是针对左侧,则会变为
std::cout << 5 * (4+1);
这就是为什么拥有volatile
个对象是不够的。必须对操作进行排序。