volatile关键字的作用是什么?在c++中它能解决什么问题?

就我而言,我从来没有明知肚明地需要它。


当前回答

您必须使用它来实现自旋锁以及一些(所有?)无锁数据结构 与原子操作/指令一起使用 曾经帮助我克服编译器的错误(在优化过程中错误地生成代码)

其他回答

在实现无锁数据结构时必须使用volatile。否则,编译器可以自由地优化对变量的访问,这将改变语义。

换句话说,volatile告诉编译器对这个变量的访问必须对应于物理内存的读/写操作。

例如,这是Win32 API中InterlockedIncrement的声明方式:

LONG __cdecl InterlockedIncrement(
  __inout  LONG volatile *Addend
);

如果你正在从内存中的某个点(比如说,一个完全独立的进程/设备/任何东西)读取数据,则需要使用Volatile。

我曾经在纯c的多处理器系统中使用双端口ram。我们使用硬件管理的16位值作为信号量,以知道另一个家伙什么时候完成。基本上我们是这样做的:

void waitForSemaphore()
{
   volatile uint16_t* semPtr = WELL_KNOWN_SEM_ADDR;/*well known address to my semaphore*/
   while ((*semPtr) != IS_OK_FOR_ME_TO_PROCEED);
}

没有volatile,优化器认为循环是无用的(这家伙从不设置值!他疯了,删掉那代码吧!),我的代码会在没有获得信号量的情况下继续运行,从而在以后造成问题。

在开发嵌入式系统或设备驱动程序时,需要使用Volatile,因为在这些驱动程序中需要读写内存映射的硬件设备。特定设备寄存器的内容随时都可能改变,所以你需要volatile关键字来确保这样的访问不会被编译器优化。

volatile关键字的目的是防止编译器对可能以编译器无法确定的方式改变的对象应用任何优化。

声明为volatile的对象在优化中被省略,因为它们的值可以被当前代码范围之外的代码随时更改。系统总是从内存位置读取volatile对象的当前值,而不是在请求时将其值保存在临时寄存器中,即使之前的指令从同一对象中请求一个值。

考虑以下情况

1)由中断服务例程在作用域外修改的全局变量。

2)多线程应用程序中的全局变量。

如果不使用volatile限定符,可能会出现以下问题

1)当优化被打开时,代码可能不会像预期的那样工作。

2)当中断被启用和使用时,代码可能不会像预期的那样工作。

Volatile:程序员最好的朋友

https://en.wikipedia.org/wiki/Volatile_ (computer_programming)

一些处理器具有超过64位精度的浮点寄存器(例如。32位x86没有SSE,见Peter的评论)。这样,如果您对双精度数运行多次操作,实际上会得到比将每个中间结果截断为64位更高精度的答案。

这通常很好,但这意味着根据编译器如何分配寄存器和进行优化,对于完全相同的输入,完全相同的操作将得到不同的结果。如果您需要一致性,那么您可以使用volatile关键字强制每个操作返回内存。

它对于一些没有代数意义但减少浮点误差的算法也很有用,比如Kahan求和。代数上它是一个nop,所以它经常会被错误地优化除非一些中间变量是不稳定的。