可以安全地读取 C 中未初始化的自动 volatile 变量吗?
Can an uninitialized automatic volatile variable in C be safely read?
在 C 中,我是否可以访问一个自动 volatile 变量而不必首先对其进行初始化,还是它总是导致未定义的行为?
例如,在某些映射到易失变量的硬件设备中,初始化变量无论如何都没有意义,甚至可能被禁止。
自动变量通常在 call stack 上(但这是特定于实现的),因此它通常不会是特定于某些硬件的 "device"(除非您的堆栈指针是垃圾)。在这种情况下(在堆栈上),变量继承自该堆栈位置的先前内容。如果它是不稳定的,例如
void foo(void) {
volatile int x;
// here x contains garbage
}
访问 x
会得到一些 "indeterminate value",并且该访问是未定义的行为。
C 标准不需要任何调用堆栈,但大多数 C 实现使用机器调用堆栈。
当然,如果你有一个自动变量,它是指向一些易失性数据的指针,情况就不同了。
访问未初始化变量(或内存位置)的值将导致 C 标准的未定义行为。这意味着 C 标准没有说明会发生什么。
还有其他来源可以定义在某些情况下会发生什么。对于 volatile 变量,所发生情况的定义几乎总是依赖于平台。
因此您需要查阅有关变量的相关文档。
如果变量是硬件内存映射的 I/O 位置,请使用 volatile,而不是 atomic,显然它应该只在硬件需要初始化时才被初始化。
C++ 11 标准规定,volatile 不应用于非硬件内存映射I/O。使用原子或其中一种同步类型(事件、互斥量、信号量等)根据需要提供 Memory Barrier。
Microsoft 和可能的其他一些编译器具有特定于供应商的扩展,这些扩展提供带有易失性变量的内存屏障(作为 VS2012 和更高版本中的命令行选项,始终在旧版本上启用),但这是非标准用法。
在 C 中,我是否可以访问一个自动 volatile 变量而不必首先对其进行初始化,还是它总是导致未定义的行为?
例如,在某些映射到易失变量的硬件设备中,初始化变量无论如何都没有意义,甚至可能被禁止。
自动变量通常在 call stack 上(但这是特定于实现的),因此它通常不会是特定于某些硬件的 "device"(除非您的堆栈指针是垃圾)。在这种情况下(在堆栈上),变量继承自该堆栈位置的先前内容。如果它是不稳定的,例如
void foo(void) {
volatile int x;
// here x contains garbage
}
访问 x
会得到一些 "indeterminate value",并且该访问是未定义的行为。
C 标准不需要任何调用堆栈,但大多数 C 实现使用机器调用堆栈。
当然,如果你有一个自动变量,它是指向一些易失性数据的指针,情况就不同了。
访问未初始化变量(或内存位置)的值将导致 C 标准的未定义行为。这意味着 C 标准没有说明会发生什么。
还有其他来源可以定义在某些情况下会发生什么。对于 volatile 变量,所发生情况的定义几乎总是依赖于平台。
因此您需要查阅有关变量的相关文档。
如果变量是硬件内存映射的 I/O 位置,请使用 volatile,而不是 atomic,显然它应该只在硬件需要初始化时才被初始化。
C++ 11 标准规定,volatile 不应用于非硬件内存映射I/O。使用原子或其中一种同步类型(事件、互斥量、信号量等)根据需要提供 Memory Barrier。
Microsoft 和可能的其他一些编译器具有特定于供应商的扩展,这些扩展提供带有易失性变量的内存屏障(作为 VS2012 和更高版本中的命令行选项,始终在旧版本上启用),但这是非标准用法。