C++ 中的 volatile 与 mutable

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2444695/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:30:36  来源:igfitidea点击:

volatile vs. mutable in C++

c++volatilemutable

提问by skydoor

I have a question about the difference between volatile and 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?

我有一个关于 volatile 和 mutable 之间区别的问题。我注意到这两者都意味着它可以改变。还有什么?它们是一样的吗?有什么不同?它们适用于哪些地方?为什么提出这两个想法?如何以不同的方式使用它们?

Thanks a lot.

非常感谢。

回答by Alex Martelli

A mutablefield can be changed even in an object accessed through a constpointer or reference, or in a constobject, so the compiler knows not to stash it in R/O memory. A volatilelocation is one that can be changed by code the compiler doesn't know about (e.g. some kernel-level driver), so the compiler knows not to optimize e.g. register assignment of that value under the invalid assumption that the value "cannot possibly have changed" since it was last loaded in that register. Very different kind of info being given to the compiler to stop very different kinds of invalid optimizations.

mutable字段即使在通过访问的对象来改变const指针或引用,或在一个const对象,所以编译器知道不藏匿它R / O存储器。一个volatile位置是一个可以通过代码编译器不知道的(例如,一些内核级驱动程序)来改变,所以编译器不知道的无效假设值“不可能有下该值的优化如寄存器分配更改”,因为它上次加载到该寄存器中。向编译器提供非常不同类型的信息以阻止非常不同类型的无效优化。

回答by xian

mutable: The mutable keyword overrides any enclosing const statement. A mutable member of a const object can be modified.

mutable: mutable 关键字覆盖任何封闭的 const 语句。可以修改 const 对象的可变成员。

volatile: The volatile keyword is an implementation-dependent modifier, used when declaring variables, which prevents the compiler from optimizing those variables. Volatile should be used with variables whose value can change in unexpected ways (i.e. through an interrupt), which could conflict with optimizations that the compiler might perform.

volatile: volatile 关键字是依赖于实现的修饰符,在声明变量时使用,可防止编译器优化这些变量。Volatile 应该用于其值可能以意外方式(即通过中断)更改的变量,这可能与编译器可能执行的优化相冲突。

Source

来源

回答by Ben Voigt

They are definitely NOT the same thing. Mutable interacts with const. If you have a const pointer, you normally could not change members. Mutable provides an exception to that rule.

它们绝对不是一回事。Mutable 与 const 交互。如果你有一个 const 指针,你通常不能改变成员。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.

另一方面,Volatile 与程序所做的更改完全无关。这意味着内存可能因编译器无法控制的原因而发生变化,因此编译器每次都必须读取或写入内存地址,并且无法将内容缓存在寄存器中。

回答by Jonathan Leffler

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 对象何时发生变化。

回答by Kyle Lutz

A variable marked mutableallows for it to be modified in a method declared const.

标记的变量mutable允许在声明的方法中对其进行修改const

A variable marked volatiletells 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告诉编译器它必须在每次您的代码告诉它时读取/写入变量(即它不能优化对变量的访问)。

回答by BinCoder

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.

我想补充一点,在处理多线程应用程序时, volatile 也非常有用,即,您拥有主线程(main() 所在的位置)并且您生成一个工作线程,该线程将在变量“app_running”为真时保持旋转。main() 控制“app_running”是真还是假,所以如果没有在“app_running”的声明中添加volatile属性,如果编译器优化了二级线程运行的代码中对“app_running”的访问,main( ) 可能会将 "app_running" 更改为 false 但辅助线程将继续运行,因为该值已被缓存。我在 Linux 和 VisualC++ 上使用 gcc 看到了相同的行为。“app_running”声明中的“volatile”属性解决了这个问题。所以,