c - 什么时候可以完全优化 volatile 变量?

标签 c language-lawyer volatile

考虑这个代码示例:

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,编译器可能会优化所有变量,因为它们永远不会被读取。

我认为 ab 可以优化掉,因为它们完全没有被使用,参见 unused volatile variable .

我认为 cd 不能删除,因为它们是写入的,并且写入 volatile 变量必须实际发生。 e 应该等同于 c

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

这些说法是真的吗?

  1. 如果从不访问 volatile 变量,则可以将其优化掉。
  2. 静态或全局变量的初始化不算作访问。

最佳答案

写入 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.

这意味着是否可以优化 ef 取决于编译器 - 但这必须记录在案!

关于c - 什么时候可以完全优化 volatile 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27816535/

相关文章:

c++ - 将 curl 结果中的字节组解释为其他数据类型的方法

c - 快速排序实现的问题,数组作为函数的参数

c++ - dynamic_cast 和右值引用

c++ - 关于静态 const 数据成员的声明和定义的困惑

Java更新程序配置

java - AtomicReferenceFieldUpdater - 方法 set、get、compareAndSet 语义

c - 所用时间 :Row major sum Column major sum

c - 使用某种文件分配表将结构存储在 EEPROM 中

C++ 列表初始化允许多个用户定义的转换

java - 如果在构造函数中分配一次,原始变量是否需要是 volatile 的