考虑ANSI C中的while循环,其唯一目的是延迟执行:
unsigned long counter = DELAY_COUNT; while(counter--);
我已经看到这很多用于强制执行嵌入式系统的延迟,例如。 没有sleep
function,定时器或中断是有限的。
我对ANSI C标准的解读是,这可以通过符合标准的编译器完全删除。 它没有5.1.2.3中描述的副作用:
访问易失性对象,修改对象,修改文件或调用执行任何这些操作的函数都是副作用,这些都是执行环境状态的变化。
……并且本节还说:
实际实现不需要评估表达式的一部分,如果它可以推断出它的值未被使用并且不产生所需的副作用(包括由调用函数或访问易失性对象引起的任何副作用)。
这是否意味着可以优化循环? 即使counter
是volatile
?
笔记:
C标准符合性遵循“as-if”规则,通过该规则,编译器可以生成任何行为“好像”它在抽象机器上运行实际指令的代码。 由于不执行任何操作具有相同的可观察行为,“就像”您执行循环一样,完全允许不为其生成代码。
换句话说,在真实机器上计算的时间不是程序“可观察”行为的一部分,它只是特定实现的一种现象。
volatile
变量的情况不同,因为访问volatile会将其视为“可观察”效果。
这是否意味着可以优化循环?
是。
即使反击是不稳定的?
不会。它会读取和写入一个具有可观察行为的volatile变量,因此必须发生。
如果计数器是volatile
,则编译器无法合法地优化延迟循环。 否则它可以。
像这样的延迟循环很糟糕,因为它们燃烧的时间取决于编译器如何为它们生成代码。 使用不同的优化选项可以实现不同的延迟,这几乎不是人们想要的延迟循环。
因此,这种延迟循环应该用汇编语言实现,程序员可以完全控制代码。 这通常适用于具有简单CPU的嵌入式系统。
标准规定了您看到的行为。 如果为DELAY_COUNT
创建依赖关系树, DELAY_COUNT
看到它具有不使用属性的修改,这意味着可以将其删除。 这是针对非易失性案例。 在易失性情况下,编译器不能使用依赖树来尝试删除此变量,因此延迟仍然存在(因为volatile意味着硬件可以更改内存映射值,或者在某些情况下意味着“我真的需要它不要抛出它离开“)如果您正在查看是否标记为volatile,它会告诉编译器,请不要将其丢弃,因为这是有原因的。
以上就是c/c++开发分享ANSI C编译器可以删除延迟循环吗?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/545937.html