C中的volatile用法

来源:互联网 发布:unity3d怎么导入模型 编辑:程序博客网 时间:2024/05/29 19:36

转载出处:http://www.cnblogs.com/chio/archive/2007/11/24/970632.html


volatile 影响编译器编译的结果,指出,volatile 变量是随时可能发生变化的,与volatile变量有关的运算,不要进行编译优化,以免出错,(VC++ 在产生release版可执行码时会进行编译优化,加volatile关键字的变量有关的运算,将不进行编译优化。)。 
例如: 
volatile int i=10; 
int j = i; 
... 
int k = i; 
volatile 告诉编译器i是随时可能发生变化的,每次使用它的时候必须从i的地址中读取,因而编译器生成的可执行码会重新从i的地址读取数据放在k中。 
而优化做法是,由于编译器发现两次从i读数据的代码之间的代码没有对i进行过操作,它会自动把上次读的数据放在k中。而不是重新从i里面读。这样以来,如果i是一个寄存器变量或者表示一个端口数据就容易出错,所以说volatile可以保证对特殊地址的稳定访问,不会出错。

/**********************

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。下面是volatile变量的几个例子: 
1) 并行设备的硬件寄存器(如:状态寄存器) 
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables) 
3) 多线程应用中被几个任务共享的变量 
回答不出这个问题的人是不会被雇佣的。我认为这是区分C程序员和嵌入式系统程序员的最基本的问题。搞嵌入式的家伙们经常同硬件、中断、RTOS等等打交道,所有这些都要求用到volatile变量。不懂得volatile的内容将会带来灾难。假设被面试者正确地回答了这是问题(嗯,怀疑是否会是这样),我将稍微深究一下,看一下这家伙是不是直正懂得volatile完全的重要性。 
1)一个参数既可以是const还可以是volatile吗?解释为什么。 
2); 一个指针可以是volatile 吗?解释为什么。 
3); 下面的函数有什么错误: 
int square(volatile int *ptr) 

return *ptr * *ptr; 

下面是答案: 
1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。 
2); 是的。尽管这并不很常见。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。 
3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码: 
int square(volatile int *ptr) 

int a,b; 
a = *ptr; 
b = *ptr; 
return a * b; 

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下: 
long square(volatile int *ptr) 

int a; 
a = *ptr; 
return a * a; 

位操作(Bit manipulation)

//*********************

嵌入式编程中经常用到 volatile这个关键字,在网上查了下他的用法可以归结为以下两点:

一:告诉compiler不能做任何优化

   比如要往某一地址送两指令: 
   int *ip =...; //设备地址 
   *ip = 1; //第一个指令 
   *ip = 2; //第二个指令 
   以上程序compiler可能做优化而成: 
   int *ip = ...; 
   *ip = 2; 
   结果第一个指令丢失。如果用volatile, compiler就不允许做任何的优化,从而保证程序的原意: 
   volatile int *ip = ...; 
   *ip = 1; 
   *ip = 2; 
   即使你要compiler做优化,它也不会把两次付值语句间化为一。它只能做其它的优化。这对device driver程序员很有用。

二:表示用volatile定义的变量会在程序外被改变,每次都必须从内存中读取,而不能把他放在cache或寄存器中重复使用。

   如   volatile char a;   
        a=0; 
       while(!a){ 
//do some things;   
       }   
       doother(); 
   如果没有 volatile doother()不会被执行

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 怀孕4个月喉咙痛怎么办 怀孕5个多月总是咳嗽尿失禁怎么办 怀孕7个月感冒了怎么办 怀孕7个月感冒喉咙痛怎么办 孕38周感冒咳嗽喉咙痛怎么办 嗓子痛咳嗽有痰怎么办 怀孕6个月了咳嗽怎么办 怀孕了咳嗽黄痰怎么办 科二5次没考过怎么办 交警开的罚单丢了怎么办 驾驶员从业资格证被水洗了怎么办 驾照考五次没过怎么办 学车每次考不过怎么办 年检超期3个月怎么办 年检超过3个月怎么办 工商执照年检时候忘记密码怎么办 个体工商营业执照年检过期怎么办 忘了审车时间怎么办 汽车年检超过时间了怎么办 星巴克金星会员到期怎么办 驾考学员证丢了怎么办 违章扣满12分怎么办 违章扣满12分后怎么办 东方时尚驾校科二考不过怎么办 东方时尚科二科三考五次没过怎么办 不想考科目三了怎么办 科目三两次没过怎么办 练科目三很紧张怎么办 驾照学员卡丢了怎么办 驾考时考试的车系统出错怎么办 驾驶证超期6个月怎么办 北京汽车年检只有电子保单怎么办 交电费户号9位数怎么办 扬州驾照12分扣完了怎么办 有大专毕业证在深圳怎么办居住证 微信解释包错误怎么办 富士康离职不批怎么办 到了怀孕年龄找不到工作怎么办 建筑公司挂靠发生人员伤残怎么办 外地生小孩落北京户口怎么办 户籍档案查不到直系亲属关系怎么办