上一篇 下一篇
C 语言编译器的优化功能


volatile 关键字的作用?

volatile:[adj] 易变的

1)基础作用

C/C++ 编译器具有优化功能:在不改变程序逻辑的前提下,让生成的代码运行更快、体积更小或更省资源。

当开启优化时,处理器会把一些高频使用的变量的值放进缓存或寄存器中,这个时候它就不从内存中取了,虽然这可以提高效率,但当这个变量的值被修改了之后(比如被多线程或中断程序修改了),CPU 没有重新访问内存,就会造成数据不一致的问题。

解决方法就是使用 volatile 关键字。

volatile 是一个类型修饰符,用于告诉编译器,该变量的值可能会被改变(是不稳定的)。然后不论如何优化,编译器每次访问该变量时,都会直接从其内存地址中读取数据(即:volatile 是让 CPU 直接去变量内存地址里去读取数据,而不是去缓存读取数据,用于防止编译器优化此变量 )。

使用举例:

volatile int flag = 1;

嵌入式必须用 volatile 的场景:

  1. 硬件寄存器(外设寄存器地址)
  2. 中断服务程序修改的全局变量
  3. 多线程/RTOS 共享变量
  4. DMA 传输的缓冲区
  5. ……

2)面试追问

① volatile 能保证原子性吗?

答:不能

解析:volatile 只保证可见性(每次都从内存读),不保证原子性。例如 volatile int count = 0; 在多线程中 count++ 仍可能被中断(读-改-写不是原子的)。原子性需要互斥锁或关中断来保证。

② volatile 能保证内存序/顺序性吗?

答:不能

解析:volatile 只阻止编译器优化对该变量本身的访问,但编译器/CPU 仍可能重排其他指令。需要 内存屏障 或 std::atomic 来保证内存序。(重排:编译器(或 CPU)认为两行代码"互相没关系",就调换它们的执行顺序来提速。这在单线程没问题,但多线程 / 硬件场景下,调换顺序就出 bug 了)

③ const volatile 是什么?用在哪儿?

答:const 关键字让程序不能修改变量,volatile 表示外部因素(硬件、中断)可能修改变量,也就是告诉编译器,这是个只读变量。典型应用在只读硬件状态寄存器。比如一个只读的 UART 状态标志寄存器,程序不能写,但硬件会改。


Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐