【问题标题】:Volatile variable易变的变量
【发布时间】:2009-11-03 05:39:38
【问题描述】:

易失性变量存储在程序存储器中的哪个部分(在哪个部分)?

【问题讨论】:

    标签: c multithreading memory volatile


    【解决方案1】:

    volatiletype qualifier 而不是storage class specifier,所以它根本无法确定存储位置;它影响变量类型的定义,而不是它的存储。

    它只是强制编译器从变量的存储位置(无论可能在哪里)显式地读取 typevolatile 的变量,而不是假设某个先前在寄存器中读取的值仍然有效。

    【讨论】:

      【解决方案2】:

      在 C 中 volatile 只是告诉编译器 - “你没有足够的知识来假设这个变量的值没有改变”。没有“部分”,例如 BSS、CSS。

      将其视为编译器的标志,以防止某些类型的优化。它在嵌入式编程中非常方便,其中某个地址的内存可能由于硬件设备输入而“改变”。

      这里有一个很好的解释:http://www.embedded.com/columns/programmingpointers/174300478?_requestid=137658

      【讨论】:

      • 优化时,编译器从哪里得到这个假定值?我的意思是内存的哪一部分?
      • 视情况而定,通常编译器“记住”该值在 CPU 寄存器中。 volatile 强制编译器永远不会做出这种假设,并在每次访问时重新加载值(通常来自主内存)。
      【解决方案3】:

      变量的波动性不会改变变量的存储位置。它所改变的是关于如何访问它的读取和写入的语义。

      我不相信 C 标准对 volatile 的实现有任何说明。但通常,易失性保证释放对变量的写操作的语义,并获得对变量的读操作的语义。但这并非适用于每个实现,您应该阅读您的特定编译器保证的内容

      【讨论】:

      • 不,它没有给出这些语义,请参阅 thisCERT 说“不要使用 volatile 进行同步”
      【解决方案4】:

      volatile 与存储类无关。

      volatile 只是告诉编译器或强制编译器对该变量“不进行优化”。 因此编译器不会优化该变量的代码并从指定位置读取值,而不是通过保存先前值的内部寄存器。

      因此,通过将变量声明为 volatile.. 可以保证您将获得最新值,该值可能会被外部事件更改。

      如果没有将该变量声明为 volatile,您的代码可能会正常工作,但有时可能无法获得正确的值。 所以为了避免我们应该将变量声明为 volatile。

      volatile 通常用于处理外部事件,例如硬件相关引脚的中断。

      例子。 读取 adc 值。

      const voltile 表示 您不能在代码中修改或更改该变量的值。只有外部事件才能改变值。

      控制器引脚通常定义为易失性。 可能是通过将变量声明为易失性控制器将执行“通过引脚读取”而不是“通过锁存器读取”......这是我的假设。可能是错的……

      但是在选择变量作为 volatile 时仍然存在很多困惑..

      当变量的值可能发生意外变化时,应将其声明为 volatile。在实践中,只有三种类型的变量可以改变:

      1. 内存映射外设寄存器

      2. 中断服务程序修改的全局变量

      3. 多线程应用程序中的全局变量

      链接:http://eetimes.com/discussion/beginner-s-corner/4023801/Introduction-to-the-Volatile-Keyword

      所以在这种情况下,它被提供为可变的变量。

      【讨论】:

        【解决方案5】:

        没有理由将 volatile 变量存储在内存的任何“特殊”部分。它通常与任何其他变量(包括非易失性变量)一起存储。如果某些编译器决定将 volatile 变量存储在内存的某个特殊部分中 - 没有什么可以阻止它这样做。但在语言层面,绝对没有理由这样做。

        你为什么要问这样的问题?是什么让您认为它应该存储在内存的某个特殊部分?

        【讨论】:

          【解决方案6】:

          “Volatile”在 C/C++ 规范中用于允许使用内存映射设备。它指示编译器不要优化使用此关键字定义的变量,只是因为该变量似乎没有在编译器可见的代码中改变其状态。

          【讨论】:

            猜你喜欢
            • 2012-09-08
            • 1970-01-01
            • 2020-06-20
            • 1970-01-01
            • 1970-01-01
            • 2014-10-26
            • 1970-01-01
            • 2012-05-26
            • 1970-01-01
            相关资源
            最近更新 更多