volatile 在 C++ 的单线程应用程序中有用吗?
Is volatile useful at all in a singlethreaded application in C++?
如标题所说 - 在任何情况下 volatile
在单线程编程的上下文中有用吗?我知道它用于确保变量的值始终在内存中实际检查,所以在任何情况下该值可能会以 app/compiler 不会注意到的方式更改(在 ST 应用程序中)?
我要离开这个问题 language-agnostic 因为我不知道它们之间的任何差异会影响对这个问题的回答。但如果有的话请告诉我。
编辑:正如我所指出的,问题不是 language-agnostic。然后我将其设为特定于 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 is even not recommended for multi-threaded use。
单线程程序也可以有信号处理甚至在非多线程平台上也可以使用硬件中断处理,所以处理函数中修改的非局部变量应该声明为volatile
.
p.s。答案或多或少是通用的,并且可能不正确,具体取决于上面已经提到的语言。
其他答案已经解决了 volatile
是什么,但我想举一个我在 volatile
有用时使用的真实示例(无需尝试阅读 from/write特殊的硬件内存位置)。
volatile
在 C 或 C++ 程序中有用的一个示例是用于调试。考虑以下示例:
void do_thing(const std::vector<int>& v) {
if (v.empty()) {
do_thing_1();
} else {
do_thing_2();
}
}
如果我想测试上面的函数并强制它在调试时取 true 或 false 分支,我可以在 if 条件中插入一个 volatile
变量:
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
变量,这样我就不必一直打断点了:我可以打一次,设置它,然后它会 "remember"我的选择。
这当然是一个 hack,但我发现它在某些特定情况下非常有用。
如标题所说 - 在任何情况下 volatile
在单线程编程的上下文中有用吗?我知道它用于确保变量的值始终在内存中实际检查,所以在任何情况下该值可能会以 app/compiler 不会注意到的方式更改(在 ST 应用程序中)?
我要离开这个问题 language-agnostic 因为我不知道它们之间的任何差异会影响对这个问题的回答。但如果有的话请告诉我。
编辑:正如我所指出的,问题不是 language-agnostic。然后我将其设为特定于 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 is even not recommended for multi-threaded use。
单线程程序也可以有信号处理甚至在非多线程平台上也可以使用硬件中断处理,所以处理函数中修改的非局部变量应该声明为volatile
.
p.s。答案或多或少是通用的,并且可能不正确,具体取决于上面已经提到的语言。
其他答案已经解决了 volatile
是什么,但我想举一个我在 volatile
有用时使用的真实示例(无需尝试阅读 from/write特殊的硬件内存位置)。
volatile
在 C 或 C++ 程序中有用的一个示例是用于调试。考虑以下示例:
void do_thing(const std::vector<int>& v) {
if (v.empty()) {
do_thing_1();
} else {
do_thing_2();
}
}
如果我想测试上面的函数并强制它在调试时取 true 或 false 分支,我可以在 if 条件中插入一个 volatile
变量:
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
变量,这样我就不必一直打断点了:我可以打一次,设置它,然后它会 "remember"我的选择。
这当然是一个 hack,但我发现它在某些特定情况下非常有用。