什么时候可以完全优化易失性变量?

Tor*_*erg 6 c volatile language-lawyer

考虑以下代码示例:

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;
}
Run Code Online (Sandbox Code Playgroud)

没有volatile编译器可以优化掉所有变量,因为它们永远不会被读取.

我认为a并且b可以被优化掉,因为它们完全未使用,请参阅未使用的volatile变量.

我认为c并且d因为它们被写入而无法删除,并且必须实际发生对volatile变量的写入.e应该相当于c.

GCC不会优化掉f,但它也不会发出任何写入指令.在数据部分中设置50.LLVM(clang)f完全删除.

这些陈述是真的吗?

  1. 如果永远不会访问volatile变量,则可以将其优化掉.
  2. 静态或全局变量的初始化不计为访问.

M.M*_*M.M 9

写入volatile变量(甚至是自动变量)计为可观察行为.

C11(N1570)5.1.2.3/6:

符合实施的最低要求是:

- 严格根据抽象机器的规则评估对易失性对象的访问.

- 在程序终止时,写入文件的所有数据应与根据抽象语义产生的程序执行的结果相同.

- 交互设备的输入和输出动态应按照7.21.3的规定进行.这些要求的目的是尽快出现无缓冲或行缓冲输出,以确保在程序等待输入之前实际出现提示消息.

这是该程序的可观察行为.

问题是:初始化(e,f)算作"访问"吗?正如Sander de Dycker所指出的那样,6.7.3说:

什么构成对具有volatile限定类型的对象的访问是实现定义的.

这意味着它是由编译器是否不ef可以被优化掉-但这必须记录在案!

  • 6.7.3说"什么构成了对具有volatile限定类型的对象的访问是实现定义的.",它解决了你的最后一段. (2认同)