volatile (C++)
Reference: MSDN
const and volatile Pointers
Reference: MSDN
volatile關鍵字是一種類型修飾符,用它聲明的類型變數表示可以被某些編譯器未知的因素更改。
用volatile關鍵字聲明的變量 i 每一次被訪問時,執行時都會從 i 相應的記憶體位址中取出 i 的值。
沒有用volatile關鍵字宣告的變數 i 在被訪問的時候可能直接從CPU的暫存器中取值
(因為之前 i 被訪問過,也就是說之前就從暫存中取出 i 的值保存到某個暫存器中)。
之所以直接從暫存器中取值,而不去記憶體中取值,是因為編譯器優化代碼的結果
(讀取CPU暫存器比讀取記憶體快得多)。
以上兩種情況的區別在於compiler時用debug mode或release mode的結果,兩者是不一樣的。會這樣做是因為變數 i 可能會經常變化(volatile),所以需保證對特殊記憶體位址的值被正確讀取。
---
volatile關鍵字是一種類型修飾符,被宣告的變數表示可以被某些編譯器未知的因素更改,例如:操作系統、硬件或者其它線程等。遇到這個關鍵字聲明的變數,編譯器對讀取該變數的程式碼就不再進行優化,從而可以提供對特殊記憶體位址的值被正確讀取。
例如:
volatile int i=10;
int a = i;
int b = i;
上面程式碼 volatile 指出 i是隨時可能發生變化的,所以每次使用它的時候必須從 i 的記憶體位址中讀取,因而編譯器生成的彙編代碼會重新從 i 的地址讀取數據放在 b 中。而優化做法是,由於編譯器發現兩次從 i 讀數據的程式碼之間的程式碼沒有對 i 進行過操作,它會自動把上次讀的數據放在b中。而不是重新從 i 裡面讀。
#include
void main()
{
int i=10;
int a = i;
printf("i= %d\n",a);
//下面彙編語句的作用就是改變記憶體中 i 的值,但是又不讓編譯器知道
__asm {
mov dword ptr [ebp-4], 20h
}
//dev c++ __asm{} must change to __asm("mov ...");
int b = i;
printf("i= %d\n",b);
}
然後,在debug mode執行程式,輸出結果如下:
i = 10
i = 32
然後,在release mode執行程式,輸出結果如下:
i = 10
i = 10
輸出的結果明顯表示,release mode下,編譯器對程式碼進行了優化,所以第二次沒有輸出正確的 i 值。
下面,我們把 i 宣告成volatile關鍵字,看看有什麼變化:
#include
void main()
{
volatile int i=10;
int a = i;
printf("i= %d\n",a);
__asm {
mov dword ptr [ebp-4], 20h
}
int b = i;
printf("i= %d\n",b);
}
分別在debug mode 和release mode 執行程式,輸出都是:
i = 10
i = 32
表示這個關鍵字發揮了它的作用!
2007年9月18日 星期二
C語言中volatile關鍵字
訂閱:
張貼留言 (Atom)
沒有留言:
張貼留言