幾個問題
1)一個參數既可以是const還可以是volatile嗎?
可以的,例如只讀的狀態寄存器。它是volatile因為它可能被意想不到地改變。它是const因為程序不應該試圖去修改它。
2) 一個指針可以是volatile 嗎?
可以,當一個中服務子程序修該一個指向一個buffer的指針時。
5.volatile的本質:
1> 編譯器的優化
在本次線程內, 當讀取一個變量時,為提高存取速度,編譯器優化時有時會先把變量讀取到一個寄存器中;以後,再取變量值時,就直接從寄存器中取值;當變量值在本線程裡改變時,會同時把變量的新值copy到該寄存器中,以便保持一致。
當變量在因別的線程等而改變了值,該寄存器的值不會相應改變,從而造成應用程序讀取的值和實際的變量值不一致。
當該寄存器在因別的線程等而改變了值,原變量的值不會改變,從而造成應用程序讀取的值和實際的變量值不一致。
2>volatile應該解釋為“直接存取原始內存地址”比較合適,“易變的”這種解釋簡直有點誤導人。
6.下面的函數有什麼錯誤:
int square(volatile int *ptr)
{
return *ptr * *ptr;
}
該程序的目的是用來返指針*ptr指向值的平方,但是,由於*ptr指向一個volatile型參數,編譯器將產生類似下面的代碼:
int square(volatile int *ptr)
{
int a,b;
a = *ptr;
b = *ptr;
return a * b;
}
由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段代碼可能返不是你所期望的平方值!正確的代碼如下:
long square(volatile int *ptr)
{
int a;
a = *ptr;
return a * a;
}
注意:頻繁地使用volatile很可能會增加代碼尺寸和降低性能,因此要合理的使用volatile。