volatile关键字是用来防止编译器在编译时对所修饰的变量做优化,例如:
unsigned char reg1; // Hardware Register #1
unsigned char reg2; // Hardware Register #2
void func (void)
{
while (reg1 & 0x01) // Repeat while bit 0 is set
{
reg2 = 0x00; // Toggle bit 7
reg2 = 0x80;
}
}
上面代码中定义了两个变量reg1和reg2,这两个变量用于访问硬件寄存器。我们的本意是,当reg1对应的寄存器的最后一个bit为1时,先向寄存器reg2写0x00,再向reg2写0x80,这样不断地循环,直到最后一个寄存器的bit1为0。
在大多数情况下,在while循环中,编译器只读取一次寄存器的状态并赋值给reg1,这样reg1的值会保持不变,即使reg1对应的寄存器的状态发生了变化。另外,代码中对reg2进行了两次赋值操作,编译器往往会把前面的赋值优化掉,只保留最后一个赋值操作。经过编译后,该程序的作用变成了:
然而这些优化操作不是我们所期望的,这时候volatile横空出世,生来就是为了解决这一问题的,它阻止了编译器对其修饰的变量做优化,让编译后的程序达到我们想要的功能。我们看一下修改后的代码:
volatile unsigned char reg1; // Hardware Register #1
volatile unsigned char reg2; // Hardware Register #2
void func (void)
{
while (reg1 & 0x01) // Repeat while bit 0 is set
{
reg2 = 0x00; // Toggle bit 7
reg2 = 0x80;
}
}