volatile
就像标题所说的那样 -在单线程编程的上下文中是否有任何有用的情况?我知道它用于确保始终在内存中实际检查变量的值,所以在任何情况下,该值可能会以应用程序/编译器不会注意到的方式发生变化(在 ST 应用程序中)?
我将这个问题与语言无关,因为我不知道它们之间的任何差异会影响这个问题的答案。但如果有的话请告诉我。
编辑:正如向我指出的那样,这个问题与语言无关。然后我将其具体化为 C++(我已经读过 C++ 版本也存在差异,但我希望它们还不足以使这个问题过于宽泛)。
volatile
就像标题所说的那样 -在单线程编程的上下文中是否有任何有用的情况?我知道它用于确保始终在内存中实际检查变量的值,所以在任何情况下,该值可能会以应用程序/编译器不会注意到的方式发生变化(在 ST 应用程序中)?
我将这个问题与语言无关,因为我不知道它们之间的任何差异会影响这个问题的答案。但如果有的话请告诉我。
编辑:正如向我指出的那样,这个问题与语言无关。然后我将其具体化为 C++(我已经读过 C++ 版本也存在差异,但我希望它们还不足以使这个问题过于宽泛)。
这是 C 和 C++ 的答案
是的!当变量映射到硬件寄存器(例如 I/O 设备)时。硬件修改寄存器,独立于应用程序。
例子:
extern volatile uint32_t MY_DEVICE_START; // write-only register
extern volatile const uint32_t MY_DEVICE_STATUS; // read-only register
extern volatile uint32_t MY_DEVICE_DATA; // read-write register
...
MY_DEVICE_DATA = 42; // send input to the device
MY_DEVICE_START = 1; // start the device
while (MY_DEVICE_STATUS == 0) {} // busy-wait for the device to finish
int result = MY_DEVICE_DATA; // read output from the device
...
至少在 C/C++ 中这是主要原因。Volatile 甚至不推荐用于多线程使用。
其他答案已经解决了问题volatile
,但我想给出一个真实的例子,我在什么时候volatile
有用(不尝试读取/写入特殊的硬件内存位置)。
volatile
在 C 或 C++ 程序中可能有用的一个示例是调试。考虑以下示例:
void do_thing(const std::vector<int>& v) {
if (v.empty()) {
do_thing_1();
} else {
do_thing_2();
}
}
如果我想测试上述函数并在调试时强制它采用真或假分支,我可以volatile
在 if 条件中插入一个变量:
void do_thing(const std::vector<int>& v) {
volatile bool condition = v.empty();
if (condition) {
do_thing_1();
} else {
do_thing_2();
}
}
我这样做是为了volatile
让优化器不会完全优化掉变量。这使得在 上设置断点变得简单if
,然后我可以修改condition
(无需修改v
)。
我也可以创建condition
一个static
变量,这样我就不必一直打断点:我可以打一次,设置它,然后它会“记住”我的选择。
当然,这是一种 hack,但我发现它在某些特定情况下非常有用。
单线程程序也可以进行信号处理,甚至在非多线程平台上也可以使用硬件中断处理,因此在处理函数中修改的非局部变量应声明为volatile
.
ps答案或多或少是通用的,并且可能不正确,具体取决于上面已经提到的语言。