考虑这个代码示例:
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
,编译器可能会优化所有变量,因为它们永远不会被读取。
我认为 a
和 b
可以优化掉,因为它们完全没有被使用,参见 unused volatile variable .
我认为 c
和 d
不能删除,因为它们是写入的,并且写入 volatile 变量必须实际发生。 e
应该等同于 c
。
GCC 不会优化掉 f
,但它也不会发出任何写入它的指令。 50设置在数据部分。 LLVM (clang) 完全删除了 f
。
这些说法是真的吗?
- 如果从不访问 volatile 变量,则可以将其优化掉。
- 静态或全局变量的初始化不算作访问。
最佳答案
写入 volatile 变量(甚至是自动变量)算作可观察的行为。
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.
— 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.
This is the observable behavior of the program.
问题是:初始化 (e
, f
) 算作“访问”吗?正如 Sander de Dycker 所指出的,6.7.3 说:
What constitutes an access to an object that has volatile-qualified type is implementation-defined.
这意味着是否可以优化 e
和 f
取决于编译器 - 但这必须记录在案!
关于c - 什么时候可以完全优化 volatile 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27816535/