在程序设计中,尤其是在C语言、C++、C#和Java语言中,使用volatile关键字声明的变量或对象通常具有与优化、多线程相关的特殊属性。
通常,volatile关键字用来阻止(伪)编译器认为的无法“被代码本身”改变的代码(变量/对象)进行优化。如在C语言中,volatile关键字可以用
来提醒编译器它后面所定义的变量随时有可能改变,因此编译后的程序每次需要存储或读取这个变量的时候,都会直接从变量地址中读取数据。
如果没有volatile关键字,则编译器可能优化读取和存储,可能暂时使用寄存器中的值,如果这个变量由别的程序更新了的话,将出现不一致的现象。
举个栗子:
在这里例子中,代码将foo
的值设置为0
。然后开始不断地轮询它的值直到它变成255
:
static int foo;
void bar(void) {
foo = 0;
while (foo != 255)
;
}
一个执行优化的编译器会提示没有代码能修改foo
的值,并假设它永远都只会是0
.因此编译器将用类似下列的无限循环替换函数体:
void bar_optimized(void) {
foo = 0;
while (true)
;
}
但是,foo可能指向一个随时都能被计算机系统其他部分修改的地址,例如一个连接到中央处理器的设备的硬件寄存器,上面的代码永远检测
不到这样的修改。如果不使用volatile关键字,编译器将假设当前程序是系统中唯一能改变这个值部分(这是到目前为止最广泛的一种情况)。
为了阻止编译器像上面那样优化代码,需要使用volatile关键字:
static volatile int foo;
void bar (void) {
foo = 0;
while (foo != 255)
;
}
这样修改以后循环条件就不会被优化掉,当值改变的时候系统将会检测到。
总结:
优点:防止编译器对代码优化,变量值是直接从变量地址中读取和存储的。
缺点: 这种使用过多会导致代码十分庞大。
参考文档: https://zh.wikipedia.org/wiki/Volatile%E5%8F%98%E9%87%8F