c/c++开发分享ANSI C编译器可以删除延迟循环吗?

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

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

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

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

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

……并且本节还说:

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

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

笔记:

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

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

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

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

    是。

    即使反击是不稳定的?

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

    如果计数器是volatile ,则编译器无法合法地优化延迟循环。 否则它可以。

    像这样的延迟循环很糟糕,因为它们燃烧的时间取决于编译器如何为它们生成代码。 使用不同的优化选项可以实现不同的延迟,这几乎不是人们想要的延迟循环。

    因此,这种延迟循环应该用汇编语言实现,程序员可以完全控制代码。 这通常适用于具有简单CPU的嵌入式系统。

    标准规定了您看到的行为。 如果为DELAY_COUNT创建依赖关系树, DELAY_COUNT看到它具有不使用属性的修改,这意味着可以将其删除。 这是针对非易失性案例。 在易失性情况下,编译器不能使用依赖树来尝试删除此变量,因此延迟仍然存在(因为volatile意味着硬件可以更改内存映射值,或者在某些情况下意味着“我真的需要它不要抛出它离开“)如果您正在查看是否标记为volatile,它会告诉编译器,请不要将其丢弃,因为这是有原因的。

      以上就是c/c++开发分享ANSI C编译器可以删除延迟循环吗?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注(猴子技术宅)。

      本文来自网络收集,不代表猴子技术宅立场,如涉及侵权请点击右边联系管理员删除。

      如若转载,请注明出处:https://www.ssfiction.com/c-cyuyankaifa/545937.html

      发表评论

      电子邮件地址不会被公开。 必填项已用*标注