关注+星标公众号,不错过精彩内容
作者 | strongerHuang
微信公众号 | strongerHuang
单片机开发初学者可能不怎么关心编译器优化的功能,但对于经验丰富的工程师来说,掌握代码优化是必备技能。今天讲述的话题就是关于代码优化中,关键字volatile在优化过程中起到的作用。分享正文之前推荐一个嵌入式招聘信息的平台:
volatile是一个类型修饰符(type specifier)。 volatile的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。volatile变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。
volatile的定义,应该在(读书)学习时都看过无数遍,但我相信绝大部分人都没有深刻理解其中含义。
当你真正编程、开发项目之后,你就会进一步理解其中含义。当你理解 volatile关键字的含义之后,你就能明白,其实很多场合都能用到 volatile关键字。单片机开发,难免会用到全局变量。一些初级工程师,更是全局变量满天飞。这种情况下,使用volatile关键字也许能减少代码bug率。单片机开发,寄存器添加volatile关键字应该是必须的,如果你平时有仔细观察,正规一点的【库】都会添加volatile关键字。具体细分的话,代码里面有很多地方都会用到 volatile关键字。我们都知道编译器有优化代码的功能,我们常用的集成开发环境(Keil、 IAR等)都有优化选项。
如果不使用关键字 volatile 申明变量,则编译器可能会对变量的访问并生成非预期的代码或删除预期的功能。#define __O volatile
#define __IO volatile
浏览代码,你会发现,很多地方都使用了“__IO”,也就是volatile.在跑系统的项目中,线程间共享的全局变量,建议都加上volatile关键字,这一点,很多人没有在意。如果未将变量用volatile声明,则编译器会假定其值不能在其定义的范围之外进行修改。因此,编译器可能会执行不需要的优化。这可以通过多种方式表现出来:void Delay(int Cnt)
{
int i;
while(Cnt--)
{
i++;
for(i=0; i<10; i++);
}
}
同样的代码,你在Keil 和 IAR环境下编译出来的延时时间也可能不一样。
当然,更深入的理解就会牵涉到汇编代码,编译之后的汇编代码会比较直观的呈现差异。
------------ END ------------关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。