关于volatile关键字

    volatile:不稳定的,易变的。他的意思告诉我们他很善变,需要多多注意一下它的举动,所以在使用这个关键字的时候需要注意一下。其实这个关键字用的很少,很多人也不知道他是什么(确实是这样的,在面试的过程中被问到了这个,当时一脸的懵啊)

    这个关键字和const类似,都是用来修饰类型的,它所修饰的变量可以被某些编译器未知的因素更改,比如操作系统,硬件,线程等等,一旦使用了volatile关键字修饰,编译器对访问该变量的代码就不再进行优化,从而提供对特殊地址的稳定访问。我们都知道对于某些变量,若是他被多次使用,编译器就不会为它重复生成从地址读取数据的汇编代码,从而提高了效率,一般是用寄存器来保存它的值,下次使用的时候直接从寄存器取值,这样的优化在某些情况下肯定会出现问题的,假如我恶意搞个破坏啊,下面请看个例子吧

void test1()
{
	int i = 10;
	int j = i;
	int k = i;
}

void test2()
{
	volatile int i = 10;
	int j = i;
	int k = i;
}
//VS2013下的代码,其汇编代码如下:


从其汇编代码看,完全一样。这应该是编译器(VS2013)的缘故吧,而且我使用的是Debug版本的,没有对代码进行优化。


下面我们通过汇编指令改变它,观察一下是否使用volatile有什么影响

void test3()
{
	int i = 10;
	int a = i;
	printf("i = %d\n",i);
	//通过汇编命令改变
	__asm{
		mov  dword ptr[ebp-4],20h
	}
	int b = i;
	printf("i = %d\n",i);
}

void test4()
{
	volatile int i = 10;
	int a = i;
	printf("i = %d\n", i);
	//通过汇编命令改变
	__asm{
		mov  dword ptr[ebp - 4], 20h
	}
	int b = i;
	printf("i = %d\n", i);	
}

//VS2013下debug和release版本的结果:

(Debug版)


(Release版)



//VC++6.0的结果如下:



可以看出,不同的编译器还是有一定的区别的,而且Debug和Release版本确实有差别,但是加过volatile修饰的话,结果应该是:10和32,VC++6.0的Debug和Ralease版本的结果都满足条件,VS2013的Debug版本没有出现预期的结果,Relase版本出现预期的版本了,这些跟编译器有关。

     我觉得基于volatile的特性,它在某些场合下可以使用:

1.volatile的这中访问属性可以用在多线程上面,在某些场合可以替代lock工作。

2.存储器映射的硬件寄存器需要使用volatile修饰

    我在《C语言深度剖析》上看到了这样的一个问题:const volatile int i = 10;这样的修饰有问题吗?

首先,const修饰的说明为只读的,不能修改。而volatile修饰则是告诉编译器不要优化,使它按照设计者的意图去执行。表面上看,一个不能变,一个易变,放到一起真的是矛盾了。其实这两个关键字是可以一起修饰的,加volatile修饰说明此变量容易被各种因素改变,再加上const修饰后提示我们本程序不应该试图去改变它,我个人觉得在这里两个关键字组合起来各有侧重点,并不矛盾。

发布了194 篇原创文章 · 获赞 88 · 访问量 45万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章