C语言 volatile的作用与使用场景
今天完成公司的任務(wù),突然想起來在調(diào)試過程中遇到了一個(gè)問題是這樣的:“我在主函數(shù)里面寫了一個(gè)while(x)的循環(huán),想在中斷里面去改變這個(gè)變量x,以達(dá)到主函數(shù)里面退出while循環(huán)的目的。但是結(jié)果并不是這樣的,我的代碼一直停在了while循環(huán)里面。后面我咨詢了一位大哥,然后他告訴我在變量i前面加上一個(gè)volatile。果然,代碼運(yùn)行和我的預(yù)期一樣了”。代碼如下
void main() {unsigned char x = 1;while(x){} }void USART1_IRQHandler(void) {x = 0 ; }那么volatile到底是做什么的呢?查閱了幾篇博客,總算是明白了其中的道道。
volatile的本意是“易變的”。因?yàn)樵L問寄存器要比訪問內(nèi)存單元快的多,所以編譯器一般都會作減少存取內(nèi)存的優(yōu)化,但有可能會讀臟數(shù)據(jù)。當(dāng)要求使用volatile聲明變量值的時(shí)候,系統(tǒng)總是重新從它所在的內(nèi)存讀取數(shù)據(jù),即使它前面的指令剛剛從該處讀取過數(shù)據(jù)。精確地說就是,遇到這個(gè)關(guān)鍵字聲明的變量,編譯器對訪問該變量的代碼就不再進(jìn)行優(yōu)化,從而可以提供對特殊地址的穩(wěn)定訪問;如果不使用valatile,則編譯器將對所聲明的語句進(jìn)行優(yōu)化。(簡潔的說就是:volatile關(guān)鍵詞影響編譯器編譯的結(jié)果,用volatile聲明的變量表示該變量隨時(shí)可能發(fā)生變化,與該變量有關(guān)的運(yùn)算,不要進(jìn)行編譯優(yōu)化,以免出錯(cuò))
看兩個(gè)例子:
1、如果你的程序是這樣的。
int num = 0 ; num = 1; num = 2;如上,你的編譯器就會去去優(yōu)化你的代碼,可能被優(yōu)化成這樣:
int num = 0 ; num = 2;結(jié)果“num = 1;”這條指令就丟失了。
但是如果你加上了volatile,你的代碼變成了這樣:
volatile int num = 0 ; num = 1; num = 2;那么你的編譯器就不再會去優(yōu)化你的代碼,你編譯出來的指令還是三條。
?
2、當(dāng)你遇到博主上面的情況時(shí),你也應(yīng)該加上volatile。第二種使用volatile的情況就是,在某個(gè)函數(shù)中定義的變量可能在函數(shù)外面被改變的情況,你就應(yīng)該加上volatile,保證每次都必須從內(nèi)存中讀取數(shù)據(jù),而不能重復(fù)使用放在cache或寄存器中的備份。
這種情況,尤其是在單片機(jī)程序,需要在中斷程序中,改變某個(gè)變量的時(shí)候,用的特別多。
?
3、當(dāng)然還有其他一些使用volatile的情況,如,存儲器映射的硬件寄存器通常也要加voliate,因?yàn)槊看螌λ淖x寫都可能有不同意義。
#define __I volatile const /*!< defines 'read only' permissions */ #define __O volatile /*!< defines 'write only' permissions */ #define __IO volatile /*!< defines 'read / write' permissions */你看你很少見到volatile,但是你肯定見到過__O、__I、__IO,被這三個(gè)定義的變量,都是必須從內(nèi)存中去讀值的。
?
好,說完了。一句話總結(jié)一下,volatile到底有什么用。它的作用就是叫編譯器不要偷懶,去內(nèi)存中去取值。
?
?
總結(jié)
以上是生活随笔為你收集整理的C语言 volatile的作用与使用场景的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转)跟我一起写 Makefile(一)
- 下一篇: QT绘图控件QWT的安装及配置