提问人:skydoor 提问时间:3/15/2010 最后编辑:Alex Bitekskydoor 更新时间:10/31/2013 访问量:52069
C++ 中的易失性与可变性
volatile vs. mutable in C++
问:
我有一个关于易失性和可变性之间的区别的问题。我注意到这两者都意味着它可以更改。还有什么?它们是一回事吗?有什么区别?它们适用于哪些地方?为什么要提出这两个想法?如何以不同的方式使用它们?
多谢。
答:
它们绝对不是一回事。可变与 const 交互。如果您有 const 指针,则通常无法更改成员。可变提供了该规则的例外。
另一方面,Volatile 与程序所做的更改完全无关。这意味着内存可能会由于编译器无法控制的原因而更改,因此编译器每次都必须读取或写入内存地址,并且无法将内容缓存在寄存器中。
评论
T
const T*
volatile
const T*
volatile
mutable
:可变关键字覆盖任何封闭的 const 语句。可以修改 const 对象的可变成员。
volatile
:volatile 关键字是与实现相关的修饰符,在声明变量时使用,可防止编译器优化这些变量。Volatile 应该与其值可能以意外方式(即通过中断)更改的变量一起使用,这可能与编译器可能执行的优化冲突。
评论
Volatile should be used with variables whose value can change in unexpected ways
即使在通过指针或引用访问的对象中,也可以在对象中更改字段,因此编译器知道不要将其存储在 R/O 内存中。位置是可以通过编译器不知道的代码(例如某些内核级驱动程序)更改的位置,因此编译器知道不要优化该值的寄存器分配,因为该值“不可能更改”,因为它上次加载到该寄存器中。向编译器提供非常不同类型的信息,以阻止非常不同类型的无效优化。mutable
const
const
volatile
评论
volatile
对象也可以由完全不涉及 CPU 的进程更改。例如,通信外设中接收字节的寄存器可以在接收到字节时自行递增(这甚至可以触发中断)。另一个示例是外设中的挂起中断标志寄存器。
volatile
x = 1; x = 0;
x
1
const
volatile
A variable marked allows for it to be modified in a method declared . mutable
const
A variable marked tells the compiler that it must read/write the variable every time your code tells it too (i.e. it cant optimize away accesses to the variable).volatile
A crude but effective way of thinking of the difference is:
- The compiler knows when a mutable object changes.
- The compiler cannot know when a volatile object changes.
评论
volatile
mutable
I would like to add that volatile is also very useful when dealing with multithreading applications, i.e, you have your main thread (where main() lives) and you spawn a worker thread that will keep spinning while a variable "app_running" is true. main() controls whether "app_running" is true or false, so if you do not add the volatile attribute to the declaration of "app_running", if the compiler optimizes access to "app_running" in the code ran by the secondary thread, main() might change "app_running" to false but the secondary thread will keep running because the value has been cached. I have seen the same behavior using gcc on Linux and VisualC++. A "volatile" attribute put in "app_running" declaration solved the problem. So, this is scenario where no hardware interrupts or kernel is invoved in changing the value of such variables.
评论