C++中volatile的作用

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寄存器。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章