volatile关键字的作用是什么?在c++中它能解决什么问题?
就我而言,我从来没有明知肚明地需要它。
volatile关键字的作用是什么?在c++中它能解决什么问题?
就我而言,我从来没有明知肚明地需要它。
当前回答
一些处理器具有超过64位精度的浮点寄存器(例如。32位x86没有SSE,见Peter的评论)。这样,如果您对双精度数运行多次操作,实际上会得到比将每个中间结果截断为64位更高精度的答案。
这通常很好,但这意味着根据编译器如何分配寄存器和进行优化,对于完全相同的输入,完全相同的操作将得到不同的结果。如果您需要一致性,那么您可以使用volatile关键字强制每个操作返回内存。
它对于一些没有代数意义但减少浮点误差的算法也很有用,比如Kahan求和。代数上它是一个nop,所以它经常会被错误地优化除非一些中间变量是不稳定的。
其他回答
我曾经在20世纪90年代早期开发过一个大型应用程序,其中包含使用setjmp和longjmp进行基于c语言的异常处理。volatile关键字对于那些值需要保存在作为“catch”子句的代码块中的变量是必要的,以免这些变量被存储在寄存器中并被longjmp清除。
volatile关键字的目的是防止编译器对可能以编译器无法确定的方式改变的对象应用任何优化。
声明为volatile的对象在优化中被省略,因为它们的值可以被当前代码范围之外的代码随时更改。系统总是从内存位置读取volatile对象的当前值,而不是在请求时将其值保存在临时寄存器中,即使之前的指令从同一对象中请求一个值。
考虑以下情况
1)由中断服务例程在作用域外修改的全局变量。
2)多线程应用程序中的全局变量。
如果不使用volatile限定符,可能会出现以下问题
1)当优化被打开时,代码可能不会像预期的那样工作。
2)当中断被启用和使用时,代码可能不会像预期的那样工作。
Volatile:程序员最好的朋友
https://en.wikipedia.org/wiki/Volatile_ (computer_programming)
我想引用Herb Sutter在GotW #95中的一句话,这有助于理解volatile变量的含义:
C++ volatile variables (which have no analog in languages like C# and Java) are always beyond the scope of this and any other article about the memory model and synchronization. That’s because C++ volatile variables aren’t about threads or communication at all and don’t interact with those things. Rather, a C++ volatile variable should be viewed as portal into a different universe beyond the language — a memory location that by definition does not obey the language’s memory model because that memory location is accessed by hardware (e.g., written to by a daughter card), have more than one address, or is otherwise “strange” and beyond the language. So C++ volatile variables are universally an exception to every guideline about synchronization because are always inherently “racy” and unsynchronizable using the normal tools (mutexes, atomics, etc.) and more generally exist outside all normal of the language and compiler including that they generally cannot be optimized by the compiler (because the compiler isn’t allowed to know their semantics; a volatile int vi; may not behave anything like a normal int, and you can’t even assume that code like vi = 5; int read_back = vi; is guaranteed to result in read_back == 5, or that code like int i = vi; int j = vi; that reads vi twice will result in i == j which will not be true if vi is a hardware counter for example).
我曾经在调试构建中使用过它,当编译器坚持要优化掉一个变量时,我希望在逐步执行代码时能够看到这个变量。
您必须使用它来实现自旋锁以及一些(所有?)无锁数据结构 与原子操作/指令一起使用 曾经帮助我克服编译器的错误(在优化过程中错误地生成代码)