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

标签 c optimization standards c89

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

unsigned long counter = DELAY_COUNT;
while(counter--);

我已经看到它经常用于在嵌入式系统上强制执行延迟,例如。没有sleep函数,定时器或中断是有限的。

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

Accessing a volatile object, modifying an object, modifying a file, or calling a function that does any of those operations are all side effects, which are changes in the state of the execution environment.

...这部分还说:

An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).

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

注意事项:

  1. 这与 Are compilers allowed to eliminate infinite loops? 不太一样,因为那指的是无限循环,并且出现了关于程序何时被允许终止的问题。在这种情况下,程序肯定会在某个时候越过这条线,无论是否优化。
  2. 我知道 GCC 的作用(移除 -O1 或更高版本的循环,除非 countervolatile),但我想知道标准规定了什么。

最佳答案

C 标准遵从“as-if”规则,根据该规则,编译器可以生成任何代码,其行为“就像”在抽象机器上运行您的实际指令。由于不执行任何操作与执行循环“就好像”具有相同的可观察行为,因此完全可以不为其生成代码。

换句话说,在真实机器上进行计算所花费的时间不是程序“可观察”行为的一部分,它只是特定实现的现象。

volatile 变量的情况不同,因为访问 volatile 算作“可观察”效果。

关于ANSI C 编译器可以删除延迟循环吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14449098/

相关文章:

windows - 应用程序应该支持哪些 "standard"应用程序返回/退出代码?

c - 为什么在 rand 中使用 1103515245?

javascript - 优化一个事件的结束日期与另一个事件的开始日期

c++ - 为什么 main 的默认返回值为 0 而不是 EXIT_SUCCESS?

c - 液晶屏坏了

c - 欧氏距离和迭代的 pagerank 代码错误

optimization - 如何使用带渐变但不调整权重的图层?

ruby-on-rails - Rails 如何优化我的网站?

代码修改以从指针读取数字数组

c - getlogin() c 函数返回 NULL 和错误 "No such file or directory"