何时才能完全优化掉易失性变量? [英] When can a volatile variable be optimized away completely?
问题描述
考虑以下代码示例:
int main(void)
{
volatile int a;
static volatile int b;
volatile int c;
c = 20;
static volatile int d;
d = 30;
volatile int e = 40;
static volatile int f = 50;
return 0;
}
在没有volatile
的情况下,编译器可以优化所有变量,因为它们从未被读取.
Without volatile
a compiler could optimize away all the variables since they are never read from.
我认为a
和b
可以被完全利用,因此可以对其进行优化,请参见未使用的volatile变量.
I think a
and b
can be optimized away since they are completely unused, see unused volatile variable.
我认为c
和d
不能删除,因为它们已被写入,并且实际上必须发生对volatile变量的写入. e
应等效于c
.
I think c
and d
can not be removed since they are written to, and writes to volatile variables must actually happen. e
should be equivalent to c
.
GCC不会优化f
,但也不会发出任何写入指令.在数据部分中设置50. LLVM(clang)完全删除了f
.
GCC does not optimize away f
, but it also does not emit any instruction to write to it. 50 is set in a data section. LLVM (clang) removes f
completely.
这些说法正确吗?
- 如果从不访问volatile变量,则可以对其进行优化.
- 静态或全局变量的初始化不算作访问.
推荐答案
写入易失性变量(甚至是自动变量)也视为可观察的行为.
Writes to volatile variables (even automatic ones) count as observable behaviour.
C11(N1570)5.1.2.3/6:
C11 (N1570) 5.1.2.3/6:
对符合标准的实现的最低要求是:
The least requirements on a conforming implementation are:
-严格根据摘要规则评估对易失对象的访问 机器.
— Accesses to volatile objects are evaluated strictly according to the rules of the abstract machine.
-在程序终止时,写入文件的所有数据应与以下结果相同: 按照抽象语义执行程序.
— At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.
-交互式设备的输入和输出动态应按照 7.21.3.这些要求的目的是无缓冲或行缓冲输出 尽快出现,以确保提示消息实际上早于 一个等待输入的程序.
— The input and output dynamics of interactive devices shall take place as specified in 7.21.3. The intent of these requirements is that unbuffered or line-buffered output appear as soon as possible, to ensure that prompting messages actually appear prior to a program waiting for input.
这是程序的可观察到的行为.
问题是:初始化(e
,f
)是否算作访问"?正如桑德·戴克(Sander de Dycker)指出的那样,6.7.3说:
The question is: does initialization (e
, f
) count as an "access"? As pointed out by Sander de Dycker, 6.7.3 says:
对具有volatile限定类型的对象的访问构成由实现定义.
What constitutes an access to an object that has volatile-qualified type is implementation-defined.
这意味着是否可以优化e
和f
取决于编译器-但这必须记录在案!
which means it's up to the compiler whether or not e
and f
can be optimized away - but this must be documented!
这篇关于何时才能完全优化掉易失性变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!