??? C/C++ 中的 volatile 關鍵字和 const 對應,用來修飾變量,通常用于建立語言級別的?memory barrier。這是 BS 在 "The C++ Programming Language" 對 volatile 修飾詞的說明:
A volatile specifier is a hint to a compiler that an object may change its value in ways not specified by the language so that?aggressive optimizations?must be avoided.
??? volatile 指出 i 是隨時可能發生變化的,每次使用它的時候必須從 i的地址中讀取,因而編譯器生成的匯編代碼會重新從i的地址讀取數據放在 b 中。而優化做法是,由于編譯器發現兩次從 i讀數據的代碼之間的代碼沒有對 i 進行過操作,它會自動把上次讀的數據放在 b 中。而不是重新從 i 里面讀。這樣以來,如果 i是一個寄存器變量或者表示一個端口數據就容易出錯,所以說 volatile 可以保證對特殊地址的穩定訪問。注意,在 VC 6 中,一般調試模式沒有進行代碼優化,所以這個關鍵字的作用看不出來。下面通過插入匯編代碼,測試有無 volatile 關鍵字,對程序最終代碼的影響:
輸入下面的代碼:
01
#include <stdio.h>
02
?
03
void?main()
04
{
05
????int?i = 10;
06
????int?a = i;
07
?
08
????printf("i = %d", a);
09
?
10
????// 下面匯編語句的作用就是改變內存中 i 的值
11
????// 但是又不讓編譯器知道
12
????__asm {
13
????????mov dword ptr [ebp-4], 20h
14
????}
15
?
16
????int?b = i;
17
????printf("i = %d", b);
18
}
??? 然后,在 Debug 版本模式運行程序,輸出結果如下:
i = 10 i = 32
??? 然后,在 Release 版本模式運行程序,輸出結果如下:
i = 10 i = 10
??? 輸出的結果明顯表明,Release 模式下,編譯器對代碼進行了優化,第二次沒有輸出正確的 i 值。下面,我們把 i 的聲明加上 volatile 關鍵字,看看有什么變化: