一個定義為volatile的變量就是說它可能會意想不到的改變(改變它的情況有很多,例如操作系統,硬件,線程),這樣,編譯器就不會去假設這個值,也就是說,當優化器讀到這個值時就會小心翼翼的去重新讀取這個變量的值,而不是使用保存在寄存器中的備份。(當使用到用類型修飾符聲明的變量時,系統總是從它所在的內存讀取,既使系統剛從這里讀取過)
Volatile修飾符告訴編譯程序不要對該變量所參與的操作進行優化。
例子
1) 並行設備的硬件寄存器。存儲器映射的硬件寄存器通常加volatile
例如狀態寄存器。以為設備寄存器會在你的程序不知道或者不介入的時候發生改變,那是因為設備寄存器可以被外設硬件修改。相反,變量中的不會變。設備寄存器的內容是易失的,或者在不注意的時候被修改。當聲明指向設備寄存器的指針時一定要用volatile它會告訴編譯 器不要對存儲在這個地址的數據進行假設,編譯器在優化這個變量時應該把它看作編譯時未知的。
#define IOPMOD (*((Volatile unsigned *)(SYSCFG + 0x5000)))
2) 一個中斷服務程序中修改的供其他程序檢測的變量。
3) 多線程應用中被幾個任務共享的變量。
擴展:
1.一個變量可以既是const 還是volatile嗎?解釋為什么?
可以,例如狀態寄存器。它首先應該是volatile 因為它可以出乎意料的修改,而且應該是const,這個寄存器程序不應該去修改。
2.一個指針可以說volatile的嗎?
可以,例如中斷服務子程序中修改一個指向buffer的指針。
3.下列代碼有錯誤嗎?
Int square(volatile int *ptr)
{
Return *ptr **ptr;
}
答:由於ptr聲明為volatile類型的所以編譯器可能編譯完的程序是:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
則得出的結果可能不是想要的結果;
正確的程序這樣寫:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}