c - 如果以下代码中没有 "volatile"关键字,编译器可以执行什么优化?

标签 c embedded volatile

以下是运行 Barrelfish 操作系统时使 Pandaboard 上的 LED 闪烁的一些代码。我的问题是,如果从 gpio_oegpio_dataout 的定义中删除了“volatile”关键字,为什么 LED 不闪烁。

static volatile uint32_t *gpio_oe = (uint32_t *)(GPIO_BASE + 0x0134);
static volatile uint32_t *gpio_dataout = (uint32_t *)(GPIO_BASE + 0x013C);

void led_flash
{
    // Enable output
    *gpio_oe &= (~(1 << 8));

    // Toggle LED on and off till eternity
    while(true)
    {
      *gpio_dataout ^= (1 << 8);  // Set means LED on; Clear means LED off
       time_delay();  // To give blinking effect
    }
}

我知道如果变量的值可以通过程序外部的源自发更改,则需要使用 volatile。但是我在这里看不到这种情况。编译器执行了什么优化使整个 while 循环使 LED 闪烁变得毫无意义?这种优化背后的逻辑是什么,即。这种优化有意义的合法案例?

最佳答案

您还需要 volatile 来强制内存写入和生成的代码访问 volatile 变量的顺序。对于常规变量,编译器可能会决定写入是不必要的,然后丢弃它们或只保留最后一个。

从评论中移出:如果编译器没有看到变量的读取,它可能根本不写任何东西,它甚至可能删除变量。

关于c - 如果以下代码中没有 "volatile"关键字,编译器可以执行什么优化?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14710318/

相关文章:

c - 如果从左到右和从右到左 - 运算符的结合性都存在于语句中,那么将考虑什么?

c - 将 PSRAM 写入 EZ Flash 3 合 1

c - 在微 Controller 上用 C 语言加密/解密小消息

c - "volatile"是否能保证多核系统的可移植 C 代码中的任何内容?

c++ - 将 char* 转换为 int 并转换回相同的 char 数组

c - 当我扫描一个数组时,它会更改另一个数组吗?

c - 结构体指针 结构体指针

c - 定义枚举类型是否有大量的内存标记?

c# - 这个 MSDN CompareExchange 示例如何不需要 volatile 读取?

java - 无法理解 volatile 字段的工作原理以及它们在共享值时如何与多个线程一起工作