【发布时间】:2017-08-18 11:32:29
【问题描述】:
为了这个问题,让我们只看volatile 变量的读取。我读过的所有讨论,唯一的结论是对声明为 volatile 的同一个变量的多次读取不能优化为单一效果。
但我认为这有点严格。考虑对一个变量进行两次读取,它们之间没有任何副作用,或者它们之间没有读取任何其他易失性变量。
现在我们知道 volatile 变量中的值可以随时更改(编译器没有提示)。但是程序员无法确保更改将发生在两次读取之间。这意味着两个读取看到相同的值是程序的有效行为。
那么编译器不能强制执行这种行为吗?进行一次读取并使用该值两次。
例如
int foo(volatile int * x) {
return *x + *x;
}
在这种情况下编译器可以进行单次读取吗?
我希望我的问题是明确的。
此外,我假设读取本身没有副作用的系统(例如计数器的增量,或每次读取时值发生变化)。或者这样的系统存在吗?
我查看了从gcc 和clang 生成的程序集,即使进行了最大优化,它们也确实插入了两个读取。我的问题是他们是否过于保守?
编辑:为了不使我的问题复杂化并避免与实现定义的子表达式评估顺序混淆,我们可以查看示例 -
int foo(volatile int * x) {
int a = *x;
int b = *y;
return a + b;
}
但我也保留了前面的示例,因为一些答案和 cmets 已经引用了该示例。
【问题讨论】:
-
此外,在这种情况下,
+的操作数的评估顺序与实现无关。程序员现在可以做任何假设吗? -
Volatile 很像高级程序集。如果您真的想“优化”,请以您自己的名义将其存储在寄存器中。
-
@TatsuyukiIshi 我同意!但是程序员不会看到可观察到的定义行为的任何变化。
-
如果你有一个标有“爆炸物”的盒子,邮递员可以把它当作非爆炸物,因为它不会经常爆炸吗?他当然可以!111!!!
-
Why is volatile needed in C? 的可能重复项很明显,声明为
volatile的变量在使用时将始终执行读取命令。即使使用序列!时期。故事结束。
标签: c compiler-construction language-lawyer volatile