ANSI C编译器可以删除延迟循环吗?

det*_*tly 5 c optimization standards c89

考虑ANSI C中的while循环,其唯一目的是延迟执行:

unsigned long counter = DELAY_COUNT;
while(counter--);
Run Code Online (Sandbox Code Playgroud)

我已经看到这很多用于强制执行嵌入式系统的延迟,例如.没有sleep功能,定时器或中断是有限的.

我对ANSI C标准的解读是,这可以通过符合标准的编译器完全删除.它没有5.1.2.3中描述的副作用:

访问易失性对象,修改对象,修改文件或调用执行任何这些操作的函数都是副作用,这些都是执行环境状态的变化.

......并且本节还说:

实际实现不需要评估表达式的一部分,如果它可以推断出它的值未被使用并且不产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用).

这是否意味着可以优化循环?即使counter是volatile?

笔记:

  1. 这与编译器允许消除无限循环不完全相同?,因为它指的是无限循环,并且出现关于何时允许程序终止的问题.在这种情况下,程序肯定会在某个时刻通过这条线,优化与否.
  2. 我知道GCC做了什么(删除循环-O1或更高,除非counter是volatile),但我想知道标准规定了什么.

Ker*_* SB 11

C标准符合性遵循"as-if"规则,通过该规则,编译器可以生成任何行为"好像"它在抽象机器上运行实际指令的代码.由于不执行任何操作具有相同的可观察行为,"就像"您执行循环一样,完全允许不为其生成代码.

换句话说,在真实机器上计算的时间不是程序"可观察"行为的一部分,它只是特定实现的一种现象.

volatile变量的情况不同,因为访问volatile会将其视为"可观察"效果.


GMa*_*ckG 9

这是否意味着可以优化循环?

是.

即使反击是不稳定的?

不会.它会读取和写入一个具有可观察行为的volatile变量,因此必须发生.