首页 文章

可以安全地读取C中未初始化的自动易失性变量吗?

提问于
浏览
3

在C中,我可以访问自动volatile变量而不必先进行初始化,还是总是导致未定义的行为?

例如,在映射到volatile变量的一些硬件设备中,初始化变量无论如何都没有意义,甚至可能被禁止 .

3 回答

  • 6

    如果变量是硬件内存映射的I / O位置,则使用volatile而不是atomic,并且显然只应在硬件需要初始化时进行初始化 .

    C 11标准规定不应将volatile用于非硬件内存映射I / O.使用原子或其中一种同步类型(事件,互斥,信号量,...)根据需要提供Memory Barrier .

    Microsoft和可能的其他一些编译器具有特定于供应商的扩展,它们使用volatile变量提供内存屏障(作为VS2012及更高版本中的命令行选项,始终在旧版本上启用),但这是非标准用法 .

  • 0

    访问未初始化的变量(或内存位置)的值将导致与C标准相关的未定义行为 . 这意味着C标准没有说明会发生什么 .

    还有其他来源可以定义在某些情况下会发生什么 . 在volatile变量的情况下,发生的事情的定义几乎总是依赖于平台 .

    因此,您需要查阅相关变量的相关文档 .

  • 1

    自动变量通常在call stack上(但这是特定于实现的),因此它通常不会是某些特定于硬件的"device"(除非您的堆栈指针是垃圾) . 在这种情况下(在堆栈上),变量继承自该堆栈位置的先前内容 . 如果它是挥发性的,例如,像

    void foo(void) {
      volatile int x;
      // here x contains garbage
    }
    

    访问 x 会给出一些"indeterminate value",并且该访问是未定义的行为 .

    C标准不需要任何调用堆栈,但大多数C实现使用机器调用堆栈 .

    当然,如果你有一个自动变量,它是一个指向一些易失数据的指针,情况会有所不同 .

相关问题