volatile 是C语言中的一个关键字,他的出场率很低,但有的时候,它的作用也是至关重要的。
在介绍这个关键字之前,我们先看一个例子。
include <stdio.h>
int main() {
const int n = 10;
int *p = (int *)&n;
*p = 20;
printf("%d\n", n);
return 0;
}
大家猜猜看这个程序的结果是什么。
10?
错了,他的结果是还是20。
但是得到这个结果的前提是开启 gcc 编译的 -O2 选项,这个选项是开启二级优化的意思,即编译器在编译期间,可能对代码进⾏优化。
当编译器看到这⾥的num被const修饰,从语义上讲这⾥的num是不期望被改变(不改变)的,那优化的时候就可以把num的值存放到寄存器(以提⾼访问的效率)中。以后只要使⽤
num的地⽅都去寄存器中取,那即使num对应的内存中的值发⽣变化,寄存器也是感知不到
的。所以造成输出10的结果。
寄存器变量有一个特点,内就是内存的不可见性。因为寄存器和内存是两片物理空间,所以存储在寄存器中的变量是无法通过指向内存空间的指针表示的。所以 *p = 20 是没有任何效果的。
我们如果对上面的程序做了如下修改
include <stdio.h>
int main() {
// 使用关键字 volatile 修饰变量
volatile const int n = 10;
int *p = (int *)&n;
*p = 20;
printf("%d\n", n);
return 0;
}
运行结果:
这就是关键字 volatile 最直观的作用表现了。
volatile
- 作用:
编译时不优化,执⾏时不缓存,每次需从内存中读出(保证内存的可⻅性)。
防止因为编译器的自动优化等动作,使某些变量放到了寄存器中,寄存器中的变量不能寻址,所以使用volatile关键字可以强制将变量存放在内存中。
- 应用场景:
⽤于多线程或多CPU编程。