91

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

非常感谢。

4

6 回答 6

118

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

于 2010-03-15T02:15:29.323 回答
28

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

volatile: volatile 关键字是一个依赖于实现的修饰符,在声明变量时使用,它会阻止编译器优化这些变量。Volatile 应该与其值可能以意想不到的方式(即通过中断)发生变化的变量一起使用,这可能与编译器可能执行的优化相冲突。

来源

于 2010-03-15T02:15:24.147 回答
22

它们绝对不是一回事。Mutable 与 const 交互。如果你有一个 const 指针,你通常不能改变成员。Mutable 为该规则提供了一个例外。

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

于 2010-03-15T02:14:50.170 回答
17

一种粗略但有效的思考差异的方法是:

  • 编译器知道可变对象何时更改。
  • 编译器无法知道 volatile 对象何时更改。
于 2010-03-15T02:30:45.067 回答
11

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

标记的变量volatile告诉编译器它必须在每次代码告诉它时读取/写入变量(即它不能优化对变量的访问)。

于 2010-03-15T02:15:56.623 回答
4

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

于 2013-10-30T18:04:59.873 回答