while (1){
if (i) dosomething();
}
}
void ISR_2(void)
{
i=1;
}
程序的本意是希望 ISR_2 中断产生时,在 main 函数中调用 dosomething 函数,但是,
由于编译器判断在 main 函数里面没有修改过 i,因此可能只执行一次对从 i 到某寄存器的
读操作,然后每次 if
“
判断都只使用这个寄存器里面的 i
”
副本 ,导致 dosomething 永远也
不会被调用。如果将变量加上 volatile 修饰,则编译器保证对此变量的读写操作都不会被
优化(肯定执行)。此例中 i 也应该如此说明。
2>多任务环境下各任务间共享的标志应该加 volatile
3>存储器映射的硬件寄存器通常也要加 voliate,因为每次对它的读写都可能有不同
意义。
例如:
假设要对一个设备进行初始化,此设备的某一个寄存器为 0xff800000。
int *output = (unsigned int *)0xff800000;//定义一个 IO 端口;
int init(void)
{
int i;
for(i=0;i< 10;i++){
*output = i;
}
}
经过编译器优化后,编译器认为前面循环半天都是废话,对最后的结果毫无影响,
因为最终只是将 output 这个指针赋值为 9,所以编译器最后给你编译编译的代码结果相当
于:
int init(void)