- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
栢图教育 /
HYPERLINK / / 栢图教育
HYPERLINK /hxg130435477/article/details/6883101 Volatile的陷阱
对于volatile关键字,大部分的C语言教材都是一笔带过,并没有做太过深入的分析,所以这里简单整理了一些关于volatile的使用注意事项。实际上从语法上来看volatile和const是一样的,但是如果const用错,几乎不会有什么问题;而volatile用错,后果可能很严重。所以在volatile的使用上,建议大家还是尽量求稳,少用一些没有切实把握的技巧。
注意volatile修饰的是谁
首先来看下面两个定义的区别:
uchar * volatile reg;
这行代码里volatile修饰的是reg这个变量。所以这里实际上是定义了一个uchar类型的指针,并且这个指针变量本身是volatile 的。但是指针所指的内容并不是volatile的!在实际使用的时候,编译器对代码中指针变量reg本身的操作不会进行优化,但是对reg所指的内容 *reg却会作为non-volatile内容处理,对*reg的操作还是会被优化。通常这种写法一般用在对共享指针的声明上,即这个指针变量有可能会被中断等函数修改。将其定义为volatile以后,编译器每次取指针变量的值的时候都会从内存中载入,这样即使这个变量已经被别的程序修改了当前函数用的时候也能得到修改后的值(否则通常只在函数开始取一次放在寄存器里,以后就一直使用寄存器内的副本)。
volatile uchar *reg;
这行代码里volatile修饰的是指针所指的内容。所以这里定义了一个uchar类型的指针,并且这个指针指向的是一个volatile的对象。但是指针变量本身并不是volatile的。如果对指针变量reg本身进行计算或者赋值等操作,是可能会被编译器优化的。但是对reg所指向的内容 *reg的引用却禁止编译器优化。因为这个指针所指的是一个volatile的对象,所以编译器必须保证对*reg的操作都不被优化。通常在驱动程序的开发中,对硬件寄存器指针的定义,都应该采用这种形式。
volatile uchar * volatile reg;
这样定义出来的指针就本身是个volatile的变量,又指向了volatile的数据内容。
volatile与const的合用
从字面上看,volatile和const似乎是一个对象的两个对立属性,是互斥的。但是实际上,两者是有可能一起修饰同一个对象的。看看下面这行声明:
extern const volatile unsigned int rt_clock;
这是在RTOS系统内核中常见的一种声明:rt_clock通常是指系统时钟,它经常被时钟中断进行更新。所以它是volatile,易变的。因此在用的时候,要让编译器每次从内存里面取值。而rt_clock通常只有一个写者(时钟中断),其他地方对其的使用通常都是只读的。所以将其声明为 const,表示这里不应该修改这个变量。所以volatile和const是两个不矛盾的东西,并且一个对象同时具备这两种属性也是有实际意义的。
?注意在上面这个例子里面,要注意声明和定义时对const的使用:
在需要读写rt_clock变量的中断处理程序里面,应该如下定义(define)此变量:
volatile unsigned int rt_clock;
而在提供给外部用户使用的头文件里面,可以将此变量声明(declare)为:
extern const volatile unsigned int rt_clock;
这样是没有问题的。但是切记一定不能反过来,即定义一个const的变量:
const unsigned int a;
但是却声明为非const变量:
extern unsigned int a;
这样万一在用户函数里面对a进行了写操作,结果是Undefined。再看另一个例子:
volatile struct devregs * const dvp = DEVADDR;
这里的volatile和const实际上是分别修饰了两个不同的对象:volatile修饰的是指针dvp所指的类型为struct devregs的数据结构,这个结构对应者设备的硬件寄存器,所以是易变的,不能被优化的;而后面的const修饰的是指针变量dvp。因为硬件寄存器的地址是一个常量,所以将这个指针变量定义成const的,不能被修改。
危险的volatile用法
下面将列举几种对volatile的不当使用和可能导致的非
您可能关注的文档
最近下载
- 班高中班主任培训 课件.ppt VIP
- 小学美术教学中趣味教学模式的运用.pptx VIP
- 宝安区地图深圳市宝安区乡镇街道地图高清矢量可填充编辑地图PPT模板.pptx
- 儿童文学教程(第4版)课件 方卫平 第5--14章 童话 寓言---- 儿童文学与小学习作教学 .ppt
- 一例儿科患者液体外渗不良事件的案例分析课件.pptx VIP
- 临近既有线施工安全方案.doc VIP
- 2023年广东省深圳市蛇口育才教育集团育才二中中考二模语文试题(含解析).pdf VIP
- 2025乌兰察布辅警考试真题.docx VIP
- 南山区地图深圳市南山区乡镇街道地图高清矢量可填充编辑地图PPT模板.pptx
- 2024-2030年中国精品咖啡行业市场深度分析及投资潜力预测报告.docx VIP
文档评论(0)