Jen*_*edt 27
volatile
变量上的限定符告诉编译器,无论何时访问此变量,其值都必须从内存加载,并且编译器可能不会假设它已经影响的先前存储的值.
因此,只要您遇到变量可能具有当前"执行线程"(广义上)无法预见的值的情况,它就是合适的.这包括:
goto
,
switch
/ case
或更重要的
setjmp
/ longjmp
.volatile
对于访问不是互斥的线程共享变量的原子访问也是必要的(但不够!).为此目的volatile
,即使只是为了阅读,也绝不足以保证原子访问.为此,您必须使用未通过当前C标准C99的抽象机器建模(或接口)的CPU的特殊指令.下一个标准C1X应该具有这样的原语.
Mar*_*ett 10
Volatile告诉编译器变量可能会在不知情的情况下发生变化 - 因此它不应该将其优化掉.
我唯一需要它的时候是在ISA卡的时候,当你读取一个内存地址来从总线获取数据时.编译器中还有一个错误,意味着挥发无效!
它在某些并行/多线程代码中也很有用
Volatile 告诉编译器这个值可能会改变,编译器不应该对它做任何优化。一个例子。
/** port to read temperature **/
#define PORTBASE 0x40000000
unsigned int volatile * const port = (unsigned int *) PORTBASE;
for(;;)
{
if(*port == 300)
{
/** shutdown the system **/
}
}
Run Code Online (Sandbox Code Playgroud)
如果端口不是易失性的,那么编译器将假定该值不能更改。如果*port == 300,它永远不会检查。但是,可以根据传感器更改该值。我们把 volatile 告诉编译器不要对它做任何优化。Thumb 规则是在使用内存映射寄存器时,其值可以根据情况变化,然后使用 volatile 关键字。