volatile关键字有什么用?

kar*_*kar 20 c c++

在C/C++中使用volatile关键字有什么用?声明变量volatile与不声明变量之间有什么区别volatile

Jen*_*edt 27

volatile变量上的限定符告诉编译器,无论何时访问此变量,其值都必须从内存加载,并且编译器可能不会假设它已经影响的先前存储的值.

因此,只要您遇到变量可能具有当前"执行线程"(广义上)无法预见的值的情况,它就是合适的.这包括:

  • 硬件寄存器
  • 信号处理程序中的状态变量
  • 在意外跳转之后使用的实时变量,例如goto, switch/ case或更重要的 setjmp/ longjmp.

volatile对于访问不是互斥的线程共享变量的原子访问也是必要的(但不够!).为此目的volatile,即使只是为了阅读,也绝不足以保证原子访问.为此,您必须使用未通过当前C标准C99的抽象机器建模(或接口)的CPU的特殊指令.下一个标准C1X应该具有这样的原语.

  • 由于这还不够,实际上也没有必要.它没有帮助.:-) (8认同)
  • @Bo,它必须与我提到的特殊指令一起使用,并且还将需要正在工作的新接口. (2认同)

Mar*_*ett 10

Volatile告诉编译器变量可能会在不知情的情况下发生变化 - 因此它不应该将其优化掉.

我唯一需要它的时候是在ISA卡的时候,当你读取一个内存地址来从总线获取数据时.编译器中还有一个错误,意味着挥发无效!

它在某些并行/多线程代码中也很有用

  • 它在嵌入式系统中也经常使用,其中各种寄存器和设备被映射到存储器地址. (2认同)

dex*_*ous 5

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 关键字。