C++ VOLATILE 关键词

黎 浩然/ 13 5 月, 2022/ C/C++, 计算机/COMPUTER/ 0 comments

the volatile keyword indicates that a value may change between different accesses, even if it does not appear to be modified. This keyword prevents an optimizing compiler from optimizing away subsequent reads or writes and thus incorrectly reusing a stale value or omitting writes

EXP1

int *output = (unsigned int *)0xff800000; //定义一个I/O端口; int init(void)
{
    int i;
    for(i=0;i< 10;i++)
    {
        *output = i;
    }
}

经过编译器优化后,编译器认为前面循环半天都是废话,对最后的结果毫无影响,因为最终只是将output这个指针赋值为9,所以编译器最后给你编译编译的代码结果相当于:

int  init(void)
{
    *output = 9; 
}

如果你对此外部设备进行初始化的过程是必须是像优化前代码一样顺序的对其赋值,显然优化过程并不能达到目的。反之如果你不是对此端口反复写操作,而是反复读操作,其结果是一样的,编译器在优化后,也许你的代码对此地址的读操作只做了一次。

这时候就该使用volatile通知编译器这个变量是一个不稳定的,在遇到此变量时候不要优化。

EXP2

static int i=0;
//volatile static int i=0; //for correctness
int main() {
    while(1)
    {
        if(i) dosomething();
    }
}
/* Interrupt service routine */
void IRS() {
    i=1; 
}

上面示例程序的本意是产生中断时,由中断服务子程序IRS响应中断,变更程序变量i,使在main函数中调用dosomething函数;但是,由于编译器判断在main函数里面没有修改过i,因此可能只执行一次对从i到某寄存器的读操作,然后每次if判断都只使用这个寄存器里面的“i副本”,导致dosomething永远不会被调用。如果将变量i加上volatile修饰,则编译器保证对变量i的读写操作都不会被优化,从而保证了变量i被外部程序更改后能及时在原程序中得到感知。

其它

  • volatile关键字声明的变量,每次访问时都必须从内存中取出值;没有被volatile修饰的变量,可能由于编译器的优化,从CPU寄存器中取值
  • const可以是volatile,如只读的状态寄存器!
  • 指针可以是volatile,此时指针指向的内存空间的读写操作是也可观测的!
Share this Post

Leave a Comment

您的邮箱地址不会被公开。 必填项已用 * 标注

*
*