关于volatile关键字
来源:互联网 发布:java编码哪个是中文的 编辑:程序博客网 时间:2024/06/06 17:22
volatile:不稳定的,易变的。他的意思告诉我们他很善变,需要多多注意一下它的举动,所以在使用这个关键字的时候需要注意一下。其实这个关键字用的很少,很多人也不知道他是什么(确实是这样的,在面试的过程中被问到了这个,当时一脸的懵啊)
这个关键字和const类似,都是用来修饰类型的,它所修饰的变量可以被某些编译器未知的因素更改,比如操作系统,硬件,线程等等,一旦使用了volatile关键字修饰,编译器对访问该变量的代码就不再进行优化,从而提供对特殊地址的稳定访问。我们都知道对于某些变量,若是他被多次使用,编译器就不会为它重复生成从地址读取数据的汇编代码,从而提高了效率,一般是用寄存器来保存它的值,下次使用的时候直接从寄存器取值,这样的优化在某些情况下肯定会出现问题的,假如我恶意搞个破坏啊,下面请看个例子吧
void test1(){int i = 10;int j = i;int k = i;}void test2(){volatile int i = 10;int j = i;int k = i;}//VS2013下的代码,其汇编代码如下:
从其汇编代码看,完全一样。这应该是编译器(VS2013)的缘故吧,而且我使用的是Debug版本的,没有对代码进行优化。
下面我们通过汇编指令改变它,观察一下是否使用volatile有什么影响
void test3(){int i = 10;int a = i;printf("i = %d\n",i);//通过汇编命令改变__asm{mov dword ptr[ebp-4],20h}int b = i;printf("i = %d\n",i);}void test4(){volatile int i = 10;int a = i;printf("i = %d\n", i);//通过汇编命令改变__asm{mov dword ptr[ebp - 4], 20h}int b = i;printf("i = %d\n", i);}
//VS2013下debug和release版本的结果:
(Debug版)
(Release版)
//VC++6.0的结果如下:
可以看出,不同的编译器还是有一定的区别的,而且Debug和Release版本确实有差别,但是加过volatile修饰的话,结果应该是:10和32,VC++6.0的Debug和Ralease版本的结果都满足条件,VS2013的Debug版本没有出现预期的结果,Relase版本出现预期的版本了,这些跟编译器有关。
我觉得基于volatile的特性,它在某些场合下可以使用:
1.volatile的这中访问属性可以用在多线程上面,在某些场合可以替代lock工作。
2.存储器映射的硬件寄存器需要使用volatile修饰
我在《C语言深度剖析》上看到了这样的一个问题:const volatile int i = 10;这样的修饰有问题吗?
首先,const修饰的说明为只读的,不能修改。而volatile修饰则是告诉编译器不要优化,使它按照设计者的意图去执行。表面上看,一个不能变,一个易变,放到一起真的是矛盾了。其实这两个关键字是可以一起修饰的,加volatile修饰说明此变量容易被各种因素改变,再加上const修饰后提示我们本程序不应该试图去改变它,我个人觉得在这里两个关键字组合起来各有侧重点,并不矛盾。
- 关于volatile关键字
- 关于volatile关键字
- 关于关键字volatile
- 关于volatile关键字
- 关于volatile关键字
- 关于java关键字volatile
- 关于线程volatile关键字
- 关于volatile关键字的说明
- 关于c中volatile关键字
- 关于c中volatile关键字
- 关于volatile和restrict关键字
- 关于Volatile和const关键字!
- 关于volatile和restrict关键字
- 关于volatile关键字的说明以及测试
- 关于volatile关键字的说明以及测试
- 关于volatile关键字的说明以及测试
- 关于volatile关键字的说明以及测试
- 关于volatile关键字的说明以及测试
- Android 四大组件的工作过程
- 杭电2069之Coin Change
- 根据main函数中对printchs函数的调用,以及printchs的功能要求,编写printchs函数,使下面的程序能输出星号图:
- Android MVP模式
- 用css样式,为表格加入边框
- 关于volatile关键字
- leetcode_c++:Missing Number(268)
- dagger2深入学习
- Greenplum或DeepGreen的管理数据
- 准备 LVM Volume Provider - 每天5分钟玩转 OpenStack(49)
- 队列和栈简单实现
- Error:(3) Error retrieving parent for item: No resource found that matches the given name 'android:T
- caption标签,为表格添加标题和摘要
- MFC使用按钮控件,满足条件下可用或者不可用