前言
C/C++中有个关键字volatile
,它是什么意思呢?有时候记得,有时候又不记得,要去查,故,小记录一下,以后查自己的。
一 正文
volatile
表示一个变量也许会被后台程序改变,关键字 volatile 是与 const 绝对对立的。它指示一个变量也许会被某种方式修改,这种方式按照正常程序流程分析是无法预知的(例如,一个变量也许会被一个中断服务程序所修改)。这个关键字使用下列语法定义:
volatile data-definition
变量如果加了 volatile 修饰,则会从内存重新装载内容,而不是直接从寄存器拷贝内容。 volatile 的作用是作为指令关键字,确保本条指令不会因编译器的优化而省略,且要求每次直接读值。
看迷糊了吧,骚年,看下面的例子2.1吧
volatile应用比较多的场合,在中断服务程序和cpu相关寄存器的定义。
二 例子
2.1 结合例子说明
//示例一
#include <stdio.h>
int main (void)
{
int i = 10;
int a = i; //优化
int b = i;
printf ("i = %d\n", b); //i = 10
return 0;
}
//示例二
#include <stdio.h>
int main (void)
{
volatile int i = 10;
int a = i; //未优化
int b = i;
printf ("i = %d\n", b);
return 0;
}
使用 volatile 的代码编译未优化。volatile 指出 i 是随时可能发生变化的,每次使用它的时候必须从 i的地址中读取,因而编译器生成的汇编代码会重新从i的地址读取数据放在 b 中。而优化做法是,由于编译器发现两次从 i读数据的代码之间的代码没有对 i 进行过操作,它会自动把上次读的数据放在 b 中。而不是重新从 i 里面读。这样以来,如果 i是一个寄存器变量或者表示一个端口数据就容易出错,所以说 volatile 可以保证对特殊地址的稳定访问。
- volatile(易变的):每次取i的值,都是从i的实际地址取。
- 没加volatile:编译器会优化,编译器发现两次从i读数据的代码之间的代码没有对i进行操作,它会自动把上次读的数据放在b中,而不是把上次读的数据放在b
volatile 使用:1.并行设备的硬件寄存器(如:状态寄存器);2.一个中断服务子程序中会访问到的非自动变量(Non-automatic variables);3.多线程应用中被几个任务共享的变量。
2.2 笔试题目
问题:C语言编译过程中,volatile关键字和extern关键字分别在哪个阶段起作用?(填空题)
解答:volatile应该是在编译阶段,extern在链接阶段。
volatile关键字的作用是防止变量被编译器优化,而优化是处于编译阶段,所以volatile关键字是在编译阶段起作用。
参考资料
[1] 聚优致成. C语言再学习 – 关键字volatile. CSDN. 2017.01.
https://blog.csdn.net/qq_29350001/article/details/54024070
[2] C语言的那些小秘密之volatile. CSDN. 2011.07.
https://blog.csdn.net/bigloomy/article/details/6645810