单片机/C语言八股:(四)volatile 关键字的作用
| 上一篇 | 下一篇 |
|---|---|
| C 语言编译器的优化功能 |
目 录
volatile 关键字的作用?
volatile:[adj] 易变的
1)基础作用
C/C++ 编译器具有优化功能:在不改变程序逻辑的前提下,让生成的代码运行更快、体积更小或更省资源。
当开启优化时,处理器会把一些高频使用的变量的值放进缓存或寄存器中,这个时候它就不从内存中取了,虽然这可以提高效率,但当这个变量的值被修改了之后(比如被多线程或中断程序修改了),CPU 没有重新访问内存,就会造成数据不一致的问题。
解决方法就是使用 volatile 关键字。
volatile 是一个类型修饰符,用于告诉编译器,该变量的值可能会被改变(是不稳定的)。然后不论如何优化,编译器每次访问该变量时,都会直接从其内存地址中读取数据(即:volatile 是让 CPU 直接去变量内存地址里去读取数据,而不是去缓存读取数据,用于防止编译器优化此变量 )。
使用举例:
volatile int flag = 1;
嵌入式必须用 volatile 的场景:
- 硬件寄存器(外设寄存器地址)
- 中断服务程序修改的全局变量
- 多线程/RTOS 共享变量
- DMA 传输的缓冲区
- ……
2)面试追问
① volatile 能保证原子性吗?
答:不能。
解析:volatile 只保证可见性(每次都从内存读),不保证原子性。例如 volatile int count = 0; 在多线程中 count++ 仍可能被中断(读-改-写不是原子的)。原子性需要互斥锁或关中断来保证。
② volatile 能保证内存序/顺序性吗?
答:不能。
解析:volatile 只阻止编译器优化对该变量本身的访问,但编译器/CPU 仍可能重排其他指令。需要 内存屏障 或 std::atomic 来保证内存序。(重排:编译器(或 CPU)认为两行代码"互相没关系",就调换它们的执行顺序来提速。这在单线程没问题,但多线程 / 硬件场景下,调换顺序就出 bug 了)
③ const volatile 是什么?用在哪儿?
答:const 关键字让程序不能修改变量,volatile 表示外部因素(硬件、中断)可能修改变量,也就是告诉编译器,这是个只读变量。典型应用在只读硬件状态寄存器。比如一个只读的 UART 状态标志寄存器,程序不能写,但硬件会改。
更多推荐

所有评论(0)