【C语言深入】[002] valotile 关键字:
前言:拒绝CP粘帖
valotile 做什么用的? 为什么要用这个关键字,它可以修饰什么? 怎么用?什么情况下可以用,什么时候不可以?
1 用法1 编译器标识:
我们知道CPU在执行PC指针的时候,往往会从内存里面读取页数据到CPU寄存器执行,为了提高系统效率,CPU在内存数据页面没有被替换的情况下,为了提高速度当然是首选访问以及载入到CPU内置算术单元的寄存器页数据,然而,这样有一个问题,就是如果读取的RAM值是一个经常改变的值(或者说根本不是一个RAM值,而是和硬件相关的memoery mapping 过来的一个硬件数据暂存器),那么就会有一个问题,CPU读取的已经载入的页面的数据和正在改变的硬件寄存器的数据是不一致的。我们一直希望,CPU还是直接访问,一直访问这个memory mapping的地址,而不是已经装载的数据,那怎么办?
valotile 就是这个目的,他是为编译器准备的,告诉编译器,这个变量是一个容易改变的变量,每次都需要你真的读取一次。这种情形下,我们一般在定义全局变量的各种数据结构的时候,都在前面加上这个关键字就好。
2 用法2 编译器优化:
还有一种情况可以用在任何暂存的堆栈函数里面,这时候,因为某些操作(尤其是硬件操作)例如,对某个硬件内存做读改写指令,需要连续写两次,编译器有的时候就会给优化了,认为你两次操作之间没有什么赋值,值应该不会变,在编译的时候,你写的第二次改写就直接屏蔽掉了,我们看汇编代码,就会发现,其实就是一次赋值,这就是编译器优化了。如果我们在这个变量前加上 valotile关键字,那么就不会优化掉这个赋值。
举例:
注意,在vc6中,一般调试模式没有进行代码优化,所以这个关键字的作用看不出来。下面通过插入汇编代码,测试有无volatile关键字,对程序最终代码的影响:
#include <stdio.h>void main(){int i=10;int a = i;printf( "i= %d\n",a);//下面汇编语句的作用就是改变内存中i的值,但是又不让编译器知道__asm {mov dword ptr [ebp-4], 20h}int b = i;printf("i= %d\n",b);}
然后,在调试版本模式运行程序,输出结果如下:
i = 10
i = 32
然后,在release版本模式运行程序,输出结果如下:
i = 10
i = 10
输出的结果明显表明,release模式下,编译器对代码进行了优化,第二次没有输出正确的i值。
下面,我们把 i的声明加上volatile关键字,看看有什么变化:
#include <stdio.h>void main(){volatile int i=10;int a = i;printf( "i= %d\n",a);__asm {mov dword ptr [ebp-4], 20h}int b = i;printf("i= %d\n",b);}
分别在调试版本和release版本运行程序,输出都是:
i = 10
i = 32
这说明这个关键字发挥了它的作用!
【巴蒂案】上面的例子是典型的编译器优化了,之前的调试模式,显然编译器选项优化选项选取不是很严格,代码的冗余量也比较大。
在正式公布版本的时候,编译器选项优化打开,造成了语句被优化了。
所以,在编写驱动程序的时候,尤其要注意,此外,release版本和公测版本的不同也有可能不是软件的bug,只是编译器的作用罢了
2 用法3 多线程使用:
valotile 就是告诉编译器要访问我的这块内存,除了,硬件驱动里面的硬件寄存器容易被改写外。还有一种情况就是多进程多线程的应用下。
有些变量很可能被IPC的作用而更改了值,需要你CPU去认真读取。
这样在一些多线程的接口函数里面也许就会有:
interface_task(valatile Interface_Data); 类似的使用等等。
ref:
1 C语言中volatile关键字的学习
http://www.chinaitlab.com/c/skill/818190.html
2 百度词条
http://baike.baidu.com/view/608706.htm
本文基本上纯手写原创,转载请注明原地址,谢谢!!! 欢迎讨论: email to 28044280@QQ.com
【C语言深入】[002] valotile 关键字:相关推荐
- c语言共有几种运算符_【填空题】C语言一共有 ()个关键字,()中控制语句,()种运算符...
[填空题]C语言一共有 ()个关键字,()中控制语句,()种运算符 更多相关问题 [填空题] 对煤进行工业分析的目的,是为了判断煤的(). [填空题] 钛的比重是不锈钢的一半,抗腐蚀性是不锈钢的(). ...
- C语言深入理解系列 - 关键字:auto和register
本文系本站原创,欢迎转载! 转载请注明出处: http://blog.csdn.net/mr_raptor/article/details/7209452 ++++++++++++++++++++++ ...
- c语言关键字中文意思,C语言的32个关键字是什么意思啊
C语言的32个关键字是什么意思啊 32个关键字是什么意思有谁知道的要简洁一点的 更新时间:2019-06-03 22:54 最满意答案 1. 数据类型关键字(12个): (1). char :声明字符 ...
- sqlite 无符号32_C语言的32个关键字
图控大叔 构图传递思想 阅读从未如此简单!!! 01 前言 今天对C语言的32个关键字做一下分类整理. 02 具体内容 对C语言的32个关键字做分类,一共可以分成四大类.如下: 具体分类如下: 数据类 ...
- java在方法中用来抛出异常关键字的是,在Java语言中以下哪个关键字用于在方法上声明抛出异常()...
在Java语言中以下哪个关键字用于在方法上声明抛出异常() 更多相关问题 [判断题] 现金到账户汇款和账户到账户汇款简称为入账汇款. [单选] 客户办理一笔134.45元按址汇款,附言5个汉字,共应收 ...
- 输入c语言用哪个关键字,在C语言中什么叫关键字,怎么用
C语言的关键字共有32个,根据关键字的作用,可分其为数据类型关键字.控制语句关键字.存储类型关键字和其它关键字四类. 1.数据类型关键字(12个): (1) char :声明字符型变量或函数 (2) ...
- 【C语言深度剖析】关键字(全)
文章目录 一.存储类型关键字 前言 补充1:内存 思考: 补充2:变量与内存的关系 补充3:变量的分类 补充4:存储类 补充5:删除数据是怎么删除的? 1.auto 2.register 3.stat ...
- 【GoLang】GO语言系列--002.GO语言基础
002.GO语言基础 1 参考资料 1.1 http://www.cnblogs.com/vimsk/archive/2012/11/03/2736179.html 1.2 https://githu ...
- C语言的32个关键字
C语言的关键字共有32个,根据关键字的作用,可分其为数据类型关键字.控制语句关键字.存储类型关键字和其它关键字四类. 1 数据类型关键字(12个): (1) char :声明字符型变量或函数 (2) ...
最新文章
- AI是万能的吗?当前AI仍面临的难题是什么?
- Android AOSP 编译sdk
- 【Flutter】Future 异步编程 ( 简介 | then 方法 | 异常捕获 | async、await 关键字 | whenComplete 方法 | timeout 方法 )
- winformC# TreeView 点击父节点,子节点全选,
- Scrapy -- 05
- python在windows安装paramiko模块
- 数据库的日常管理经验浅谈
- Vue2 彻底从 Flow 重构为 TypeScript,焕然一新!
- 【线性代数本质】4:矩阵乘法本质
- Docker解析及轻量级PaaS平台演练(三)--Dockerfile编写
- (201)数字6种表示方式
- 长沙android工程师,长沙安卓工程师辅导
- luogu P2381 圆圆舞蹈
- mysql中身份证号判断男女人数
- 2022年荧光染料市场前景分析及研究报告
- gsoap 的好网站 http://www.cs.fsu.edu/~engelen/soapexamples.html
- 手把手教学--Python爬取有道词典
- ps打造人物光滑的肤色
- python发送文件_Python发送邮件(最全)
- 【译】迁移被废弃的Kotlin Android Extensions插件
热门文章
- 【.NET框架】—— ASP.NET MVC5路由基础(五)
- java Set无序集合 HashSet 的对象元素唯一性
- 【Python】获取星期字符串
- C#LeetCode刷题之#643-子数组最大平均数 I( Maximum Average Subarray I)
- C#算法设计排序篇之03-直接插入排序(附带动画演示程序)
- 如何在Telegram机器人中设置推送通知
- fastify 后台_如何使用Fastify启动和运行
- CMakeLists.txt使用boost库
- Java-优先级队列(堆)
- 短信hz,批量注册、模拟登陆很难吗?一个Python爬虫案例告诉你答案!