简体   繁体   English

C ++中的volatile与mutable

[英]volatile vs. mutable in C++

I have a question about the difference between volatile and mutable. 我对volatile和mutable之间的区别有疑问。 I noticed that both of the two means that it could be changed. 我注意到这两个都意味着它可以改变。 What else? 还有什么? Are they the same thing? 它们是一样的吗? What's the difference? 有什么不同? Where are they applicable? 它们适用于哪里? Why the two ideas are proposed? 为什么提出这两个想法? How to use them in different way? 如何以不同的方式使用它们?

Thanks a lot. 非常感谢。

A mutable field can be changed even in an object accessed through a const pointer or reference, or in a const object, so the compiler knows not to stash it in R/O memory. 即使在通过const指针或引用访问的对象中,或在const对象中,也可以更改mutable字段,因此编译器知道不将其存储在R / O存储器中。 A volatile location is one that can be changed by code the compiler doesn't know about (eg some kernel-level driver), so the compiler knows not to optimize eg register assignment of that value under the invalid assumption that the value "cannot possibly have changed" since it was last loaded in that register. volatile位置是可以通过编译器不知道的代码(例如某些内核级驱动程序)更改的位置,因此编译器知道不会在无效假设值“不可能”的情况下优化例如该值的寄存器赋值已更改“因为它最后一次加载到该寄存器中。 Very different kind of info being given to the compiler to stop very different kinds of invalid optimizations. 为编译器提供了非常不同类型的信息,以阻止非常不同类型的无效优化。

mutable : The mutable keyword overrides any enclosing const statement. mutable :mutable关键字覆盖任何封闭的const语句。 A mutable member of a const object can be modified. 可以修改const对象的可变成员。

volatile : The volatile keyword is an implementation-dependent modifier, used when declaring variables, which prevents the compiler from optimizing those variables. volatile :volatile关键字是一个依赖于实现的修饰符,在声明变量时使用,这会阻止编译器优化这些变量。 Volatile should be used with variables whose value can change in unexpected ways (ie through an interrupt), which could conflict with optimizations that the compiler might perform. Volatile应该与变量一起使用,其值可能以意外的方式(即通过中断)发生变化,这可能与编译器可能执行的优化冲突。

Source 资源

They are definitely NOT the same thing. 他们绝对不是一回事。 Mutable interacts with const. Mutable与const交互。 If you have a const pointer, you normally could not change members. 如果你有一个const指针,你通常无法更改成员。 Mutable provides an exception to that rule. Mutable为该规则提供了一个例外。

Volatile, on the other hand, is totally unrelated to changes made by the program. 另一方面,易失性与程序的变化完全无关。 It means that the memory could change for reasons beyond the control of the compiler, therefore the compiler has to read or write the memory address every time and can't cache the content in a register. 这意味着内存可能因编译器无法控制的原因而发生更改,因此编译器必须每次都读取或写入内存地址,并且无法将内容缓存在寄存器中。

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对象何时发生更改。

A variable marked mutable allows for it to be modified in a method declared const . 标记为mutable的变量允许在声明为const的方法中对其进行修改。

A variable marked volatile tells the compiler that it must read/write the variable every time your code tells it too (ie it cant optimize away accesses to the variable). 标记为volatile的变量告诉编译器每次代码都告诉它必须读/写变量(即它不能优化对变量的访问)。

I would like to add that volatile is also very useful when dealing with multithreading applications, ie, 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. 我想补充一点,volatile在处理多线程应用程序时也非常有用,也就是说,你有主线程(main()存在),并且你产生一个工作线程,当变量“app_running”为真时它会继续旋转。 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. main()控制“app_running”是真还是假,所以如果你没有将volatile属性添加到“app_running”的声明中,如果编译器优化了对辅助线程运行的代码中“app_running”的访问,则为main( )可能会将“app_running”更改为false,但辅助线程将继续运行,因为该值已被缓存。 I have seen the same behavior using gcc on Linux and VisualC++. 我在Linux和VisualC ++上使用gcc看到过相同的行为。 A "volatile" attribute put in "app_running" declaration solved the problem. 放入“app_running”声明的“volatile”属性解决了这个问题。 So, this is scenario where no hardware interrupts or kernel is invoved in changing the value of such variables. 因此,这是在更改此类变量的值时不会发生硬件中断或内核的情况。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM