-
作用
防止编译器对可能以编译器无法确定的方式更改的对象应用任何优化
volatile int *p = /* ... */ ; int a, b; a = *p; b = *p;
说明:若忽略
volatile
,那么p
就只是一个「指向int
类型的指针」。这样一来,a = *p;
和b = *p;
两句,就只需要从内存中读取一次就够了。因为从内存中读取一次之后,CPU 的寄存器中就已经有了这个值;把这个值直接复用就可以了。这样一来,编译器就会做优化,把两次访存的操作优化成一次。这样做是基于一个假设:我们在代码里没有改变p
指向内存地址的值,那么这个值就一定不会发生改变。
-
例子
int etx_rcvd = false;
void main()
{
...
while (!ext_rcvd)
{
// Wait
}
...
}
interrupt void rx_isr(void)
{
...
if (ETX == rx_char)
{
etx_rcvd = TRUE;
}
...
}
- 解析:如果编译器优化选项没打开, 这段代码或许能够正常运行. 但现在像样的编译器都会 "破坏" 上面代码的逻辑, 问题在于 "编译器不知道
etx_rcvd
会在一个中断服务中被改变。 在编译器看来,!ext_rcvd
总是正确的,所以你将永远无法退出循环。 更甚至, 所有while() {}
循环体后面的代码会因优化而全部被移除 -- 因为它们永远得不到执行。