【问题标题】:Volatile is not preventing a variable from being optimized易失性不会阻止变量被优化
【发布时间】:2019-07-22 13:47:13
【问题描述】:

据我所知,“volatile”关键字用于防止编译器优化未使用的变量。我正在使用 STM32 板,我声明并初始化一个变量,如下所示;

volatile uint32_t errorCallbackCounter = 24 ;

永远不要再使用它。

调试时看不到这个变量。我正在用 STMStudio(实时变量观察器)检查它,当我想导入变量时,errorCallbackCounter 的地址被视为 0x0。

但是当我在任何地方使用它时,它就会变得可见。

所以 volatile 关键字没有发挥作用,或者 - 更有可能 - 我知道它有问题。

提前致谢。

【问题讨论】:

    标签: c memory volatile


    【解决方案1】:

    链接器可以删除从不使用的变量

    volatile 关键字影响访问变量的代码,防止编译器重新排列或删除 access。上面的行是一个带有初始化器的变量definition,它不算作访问,它在main() 开始之前被安排。但是如果它没有被accessible程序代码引用,根本就没有被访问,那么链接器就认为删除它是安全的,没有人会注意到。 p>

    但是,您可以将变量标记为“无论如何都需要”

    __attribute__((used))
    

    放在定义的末尾。这适用于gcc,其他编译器可能有另一个指令。还有一个链接器选项,我现在想不起来在可执行文件中包含所有未使用的数据部分。

    【讨论】:

    • 谢谢,这很好地回答了我的问题。如果您有时间,请在上述答案的评论部分查看我的示例(以检查我是否正确)。
    【解决方案2】:

    volatile 表示每次访问该变量时系统都会从内存中加载该变量。 不允许编译器将数据直接存储到寄存器中。

    volatile 关键字防止编译器对涉及 volatile 对象的代码进行优化,从而确保每个 volatile 变量赋值和读取都有对应的内存访问。如果没有 volatile 关键字,编译器就知道变量不需要在每次使用时从内存中重新读取,因为不应该有任何其他线程或进程对其内存位置的任何写入。

    【讨论】:

    • 嘿,谢谢你的回答,所以我对 volatile 的理解有点错误。那么,您知道我的问题的任何解决方案吗?或者您知道为什么吗?是不是其他优化问题?
    • 我不知道你为什么想要一个从未使用过的变量,但我认为如果你在代码中至少读过一次,编译器就会创建它。
    • 我不需要它用于任何特定目的,我只是对它感到好奇。所以volatile 会在这样的场景中有所作为,那么int a=5; while(a){} 可能会在优化后导致absolute 无限循环。另一方面,在volatile int a=5; while(a){} 的情况下,处理器将一直检查变量a 的值。我现在正确吗?谢谢。
    • @muyustan 是的,第一个会永远等待,后一个会一直等到a 以某种方式变成0,例如由信号或中断处理程序更改。
    猜你喜欢
    • 1970-01-01
    • 2023-03-07
    • 1970-01-01
    • 2012-12-19
    • 2016-01-25
    • 2019-03-06
    • 2023-03-21
    • 2010-09-11
    • 1970-01-01
    相关资源
    最近更新 更多