C + + 中的可变对易变

我有一个关于易变性和易变性的区别的问题。我注意到这两者都意味着它可以被改变。还有呢?它们是一样的吗?有什么区别吗?它们适用于哪些领域?为什么提出这两个观点?如何以不同的方式使用它们?

非常感谢。

50810 次浏览

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.

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.

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

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.

Source

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. A volatile location 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.

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

A variable marked volatile 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).

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.

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.