volatile的作用
volatile关键字是一个类型修饰符,用它声明的类型变量表示随时可能被某编译器未知的因素的修改。比如OS,hardware or other threads.简单来说,如果一个变量使用了volatile进行修饰,那么每次去读取该值的时候是从对应的地址中去读取,而不会因为编译器发现程序中间没有对该值进行操作所以不从内存而是从上次读到的数据进行操作(这个就是编译器的优化,而使用了volatile关键字表示编译器不对次进行优化,每次都从对应的内存中读取)。这样就保证了对特殊地址的稳定访问。
实例
无volatie
#include <stdio.h>
void main()
{
int i = 10;
int a = i;
printf("i = %d", a);
// 下面汇编语句的作用就是改变内存中 i 的值
// 但是又不让编译器知道
__asm {
mov dword ptr [ebp-4], 20h
}
int b = i;
printf("i = %d", b);
}
结果:
i = 10
i = 10
有volatile
#include <stdio.h>
void main()
{
volatile int i = 10;
int a = i;
printf("i = %d", a);
__asm {
mov dword ptr [ebp-4], 20h
}
int b = i;
printf("i = %d", b);
}
结果:
i = 10
i = 32
volatile使用场景
- 中断服务程序中修改的供其他程序检测的变量
- 多任务环境下各任务之间共享的变量
- 存储器映射的硬件寄存器
- 有些变量是用 volatile 关键字声明的。当两个线程都要用到某一个变量且该变量的值会被改变时,应该用 volatile 声明,该关键字的作用是防止优化编译器把变量从内存装入 CPU 寄存器中。如果变量被装入寄存器,那么两个线程有可能一个使用内存中的变量,一个使用寄存器中的变量,这会造成程序的错误执行。volatile 的意思是让编译器每次操作该变量时一定要从内存中真正取出,而不是使用已经存在寄存器中的值,
volatile指针
修饰指针指向的对象、数据是volatile的
volatile char* vpch;
修饰指针自身的值——代表地址的整数变量
char* volatile pchv;
注意
- 可以把一个非volatile int值赋值给volatile int,反之不行
- 除了基本类型, 对用户定义类型也可以使用volatile类型修饰
- C++中一个有volatile标识符的类只能访问它接口的子集,一个由类的实现者控制的子集。用户只能用const_cast来获得对类型接口的完全访问。此外,volatile向const一样会从类传递到它的成员