volatile的語法和const的是一樣的,但是volatile的意思是「在編譯器認識的範圍外,這個資料可以改變」。環境正在改變資料(可能通過多工、多執行緒或者中斷處理),所以,volatile告訴編譯器不要擅自做出有關該資料的任何假定,優化期間尤其如此。
volatile的本意是一般有兩種說法--1.「暫態的」;2.「易變的」。
其實volatile是由於編譯器優化所造成的乙個bug而引入的關鍵字。
int a = 10;
int b = a;
int c = a;
理論上來講每次使用a的時候都應該從a的位址來讀取變數值,但是這存在乙個效率問題,就是每次使用a都要去記憶體中取變數值,然後再通過系統匯流排傳到cpu處理,這樣開銷會很大。所以那些編譯器優化者故作聰明,把a讀進cpu的cache裡,像上面的**,假如a在賦值期間沒有被改變,就直接從cpu的cache裡取a的副本來進行賦值。但是bug也顯而易見,當a在賦給b之後,可能a已經被另乙個執行緒改變而重新寫回了記憶體,但這個執行緒並不知道,依舊按照原來的計畫從cpu的cache裡讀a的副本進來賦值給c,結果不幸發生了。
於是編譯器的開發者為了補救這一bug,提供了乙個volatile讓開發人員為他們的過失埋單,或者說提供給開發人員了乙個選擇效率的權利。當變數加上了volatile時,編譯器就老老實實的每次都從記憶體中讀取這個變數值,否則就還按照優化的方案從cache裡讀。
volotile -->該變數為乙個共享變數,也就是說會有除了本程式之外的其他途徑對其值進行更改,如多執行緒,或是其他的執行程式.
也就是防止編譯器對其進行優化而造成不必要的麻煩
一般與const一起用在某些變數的定義中,如const volatile unsigned char *port=0x30
const volatile禁止編譯器優化,所謂編譯器優化是指當乙個變數被宣告為const時,編譯器認為該變數在某一段**(如乙個函式)中不會發生改變,就會將該變數儲存到cpu的暫存器,從cpu暫存器讀寫資料的速度要遠遠快於從記憶體讀取資料。
const volatile禁用了編譯器優化,也就是說,不允許將該資料儲存到cpu暫存器。
儲存到cpu暫存器的變數可能在某些情況下被改編,例如,另乙個執行緒可能會改變該暫存器得值, 這樣就會導致你原本以為是const的變數發生了改變,導致了bug。
使用const volatile宣告就避免了這種情況。
1、volatile 是保證訪問的變數不被編譯器優化
比如申請的變數 a = 1; 如果嵌入彙編饒開編譯器
將a位址內容1改變掉
而你不加volatile就還是原來的1
如果加了則會保證每次資料均是從a的位址處讀出
4、暫存器操作一定要加! 一般的驅動程式裡的埠操作也需要加, volatile只是保證你每次取變數位址都是從此變數的源位址取值! 比如宣告 乙個變數uint16 portaddress=0x0001; 下面的**中再也沒有對 portaddress進行賦值,如果沒加 volatile,則你每次用portaddress變數時系統會直接取1, 而不是去portaddress的位址去取他的值,如果 portaddress是硬體相關的,則可能會因為硬體的原因把他的值改變了(不再是0x0001),從而造成執行出錯!
一句話: 取消編譯器對此修飾變數的任何優化, 所有對此資料操作都去相應位址中讀寫 而不會取自因優化而暫存的暫存器中。
用volatile關鍵字宣告變數,是用來告訴編譯器每次對此變數的引用都需要從記憶體位址中讀取,即取消編譯器對此變數的優化編譯。
沒用volatile宣告的變數,當某次引用時,被編譯器從記憶體位址中讀取到ax暫存器,那麼在其後的引用中,如果ax暫存器沒有被改編,那麼編譯器會優化成直接讀取ax暫存器。
C 中volatile的用法
恐怕比較一下volatile和synchronized的不同是最容易解釋清楚的。volatile是變數修飾符,而synchronized則作用於一段 或方法 看如下三句get inti1 intgeti1 volatile inti2 int geti2 int i3 synchronized in...
C中的volatile用法
volatile 影響編譯器編譯的結果,指出,volatile 變數是隨時可能發生變化的,與volatile變數有關的運算,不要進行編譯優化,以免出錯,vc 在產生release版可執行碼時會進行編譯優化,加volatile關鍵字的變數有關的運算,將不進行編譯優化。例如 volatile int i...
C中的volatile用法
volatile 影響編譯器編譯的結果,指出,volatile 變數是隨時可能發生變化的,與volatile變數有關的運算,不要進行編譯優化,以免出錯,vc 在產生release版可執行碼時會進行編譯優化,加volatile關鍵字的變數有關的運算,將不進行編譯優化。例如 volatile int i...