在C ++中的volatile和mutable
我有一个关于volatile和mutable之间的区别的问题。 我注意到两者都意味着它可以被改变。 还有什么? 它们是一样的吗? 有什么不同? 他们在哪里适用? 为什么提出这两个想法? 如何以不同的方式使用它们?
非常感谢。
即使在通过const
指针或引用或const
对象访问的对象中,也可以更改mutable
字段,所以编译器不会将其存储在R / O内存中。 一个volatile
位置是一个可以被编译器不知道的代码(例如某个内核级别的驱动程序)改变的位置,所以编译器知道不会优化例如寄存器赋值,这个值在无效的假设下是不可能的已经改变了“,因为它是最后一次加载到该registry中。 给编译器提供了非常不同的信息来阻止非常不同的无效优化。
mutable
:mutable关键字覆盖任何封闭的const语句。 一个const对象的可变成员可以被修改。
volatile
:volatile关键字是一个依赖于实现的修饰符,用于声明variables时,这会阻止编译器优化这些variables。 易失性应该与其值可能以意想不到的方式改变(即通过中断)的variables一起使用,这可能与编译器可能执行的优化相冲突。
资源
他们绝对不是一回事。 可变与const交互。 如果你有一个const指针,你通常不能改变成员。 Mutable为该规则提供了一个例外。
另一方面,挥发性与程序的改变完全无关。 这意味着内存可能会因编译器控制之外的原因而改变,因此编译器每次都必须读取或写入内存地址,而不能将内容caching到寄存器中。
粗略而有效的思维方式是:
- 编译器知道一个可变对象何时改变。
- 编译器无法知道易失性对象何时更改。
标记为mutable
的variables允许在声明为const
的方法中对其进行修改。
一个标记为volatile
的variables告诉编译器,每当代码告诉它时它必须读/写这个variables(即它不能优化对variables的访问)。
我想补充一点,在处理multithreading应用程序时,volatile也是非常有用的,也就是说,你有你的主线程(main()存在),并且产生一个工作线程,当一个variables“app_running”为真时,它将继续旋转。 main()控制“app_running”是true还是false,所以如果你不把volatile属性添加到“app_running”声明中,如果编译器在辅助线程运行的代码中优化对“app_running” )可能会将“app_running”更改为false,但由于该值已被caching,所以辅助线程将继续运行。 我已经看到在Linux和VisualC ++上使用gcc的相同行为。 放在“app_running”声明中的“volatile”属性解决了这个问题。 所以,这是没有硬件中断或内核被用来改变这些variables的值的情况。