当前位置:编程学习 > C/C++ >>

C++关键字volatile解析

  volatile在英文中的解释是“不稳定的”,也就是说用该关键字修饰的变量的值随时可能被改变。用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。 volatile的本意是“易变的”,不过翻译成“直接存取原始内存地址”更为合适。“易变”是因为外在因素引起的,象多线程,中断等,并不是因为用volatile修饰了的变量就是“易变”了,假如没有外因,即使用volatile定义,它也不会变化。
     计算机中进行计算时,通常会将数据拷贝到寄存器中,因为CPU对寄存器的操作远快于对内存的操作。
    在变量没有使用volatile修饰时,如果在计算过程中没有对该变量所在的寄存器操作,计算机将认为该变量的值没有变化,于是他就直接从寄存器中取值进行操作,而不会从内存/变量的源地址中取值。
    但是,如果变量使用了volatile关键字,则表明该变量的值随时可能在编译器认知的范围之外被改变(例如在终端中被改变或者多任务、多线程)。而此时volatile关键字的作用就是告诉编译器,不能擅自作出关于变量的值未改变的假设,每次进行计算时都从新从变量的源地址中取值,而不是取存放在寄存器中的拷贝。
    volatile关键字的语法和const的语法一样。
    总之,关键字volatile作用是取消编译器对被修饰的变量的任何优化,当对该变量进行操作时每次都是从他的源地址中读写,而不是从暂存数据的寄存器中读取,即取消编译器对此变量的优化。
    下面是几个例子:
例子1、
void delay(int time)
{
for(;time>0;time--);
}
上面这段代码本意是实现一个非精确的延时操作,通常来说没有什么问题,但是为了优化代码,打开了编译器的优化功能之后,这个函数将会被优化掉。因为,编译器发现这个函数实际上什么也没有做,为了提高性能编译器就会将这段代码优化掉。
为了防止被编译器优化掉,这段代码可以改成下面:
volatile void delay(int time)//这里用关键字volatile告诉编译器不要讲这段代码优化
{
for(;time>0;time--);
}
例子2、
float square(volatile float *ptr)
{
return *ptr * *ptr;
}
这段代码的问题在于形参使用了volatile关键字修饰,从而导致在调用这个函数的过程中*ptr的值可能被意外改变,其实它的过程如下  www.zzzyk.com
float square(volatile float *ptr)
{
float a, b;
a=*ptr;//在给a赋值之后,如果程序进入到中断中改变了*ptr的值,则b的值和a不同
b=*ptr;
return a * b;
}
以上代码应该改成:
float square(volatile float *ptr)
{
float a, b;
a=*ptr;
return a * a;
}
一般说来,volatile用在如下的几个地方:

中断服务程序中修改的供其它程序检测的变量需要加volatile;
多任务环境下各任务间共享的标志应该加volatile;
存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。
    另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。

作者:qingtingchen1987
 

补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,