浅谈volatile变量

       volatile这个关键词很多朋友都听说过,或许也使用过。但是却不明不白,备受争议,因为在程序中使用往往会导致出人意料的结果。下面就谈谈我自己的看法:volatile是一个类型修饰符,它是被设计用来修饰被不同线程访问和修改的变量。volatile是确保本条指令不会因编译器的优化而省略,且要求每次直接读值。
        编译器读取数据时寄存器优先读取,在寄存器中找不到数据才从缓存、内存读取。这就导致了可能暂时使用寄存器数据,而在内存中更新了,出现数据不一致。下面举个这样的例子:这是一个纯c写的代码,num作为一个被const修饰的常变量,是不能直接进行修改的。在这我们用地址进行修改的,朋友可不要学哦!毕竟是违规操作。在这我们为了说明就这么用用吧。之后我们运行段代码,在纯c的编译环境下,输出为“num = 20”,而在c++的编译环境下,输出的却为“num = 10”。
 
 
#include<stdio.h>
int main( )
{const int num = 10;
int *p = (int *)&num;
*p = 20;
printf("num = %d\n",num);
return 0;
}
        为什么会出现这样的结果呢?因为在纯c的编译器下不会自动进行优化,而c++编译器下编译器会自动进行优化。也就是用const关键词编译器就会将它认为是常量,就会将数据放在寄存器里,用的时候直接从寄存器里取,就不会再内存中找更新之后的数据,就会出现数据不一致。这时,我们要避免出现这样的问题,就需要使用volatile关键词。如下代码:
 
  
#include<stdio.h>
int main( )
{volatile const int num = 10;
int *p = (int *)&num ;
*p = 20;
printf("num = %d\n",num);
return 0;
}
        这时在c++的编译器下输出的结果为“num = 20”,由于volatile关键词,编译器会返回到内存中找数据,这样就避开了数据不一致导致的错误。如果在Linux纯c环境中,采用-02优化,就会造成和c++编译环境下出现的结果一样。这时,我们一样要使用volatile关键词。
        如有不足之处请见谅,并批评指正。

猜你喜欢

转载自blog.csdn.net/yunhaoyoung/article/details/80029762