一个定义为volatile的变量,编译器(优化器)每次用到这个变量时必须从该变量的地址处读取该值,而不是保存在寄存器里的备份。
比如:
①多线程应用中被几个任务共享的变量。
②并行设备的硬件寄存器(如状态寄存器)。
③一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)。
Q1:一个参数既可以是const还可以是volatile吗?
volatile修饰符告诉complier变量值可以以任何不被程序明确指明的方式改变,最常见的例子就是外部端口的值,他的变化可以不用程序内的任何赋值语句就有可能改变的,这种变量就可以用volatile来修饰,complier不会优化掉他。
const修饰的变量在程序里面是不能改变的,但是可以被程序外的东西修改,就像上面说的外部端口的值,如果仅仅使用const,有可能complier会优化掉这些变量,加上volatile就万无一失了。
Q2:一个指针可以是volatile吗?
是的,当一个中断服务子程序修改一个指向一个buffer的指针时。
Q3:下面的函数有什么错误?
int square(volatile int * ptr)
{
return *ptr * *ptr;
}
这段代码的目的是用来返回指针*ptr所表示值得平方,但是由于*ptr是一个volatile的值,编译器将会产生类似下面的代码:
int square(volatile int * ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a*b;
}
由于*ptr的值可能被意想不到地改变,因此a和b可能是不同的,结果,这段代码可能返回的不是你所期望的值!
正确的代码应该如下:
int square(volatile int * ptr)
{
int a;
a = *ptr;
return a*a;
}