關於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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章