C语言 volatile的作用与使用场景
今天完成公司的任務,突然想起來在調試過程中遇到了一個問題是這樣的:“我在主函數里面寫了一個while(x)的循環,想在中斷里面去改變這個變量x,以達到主函數里面退出while循環的目的。但是結果并不是這樣的,我的代碼一直停在了while循環里面。后面我咨詢了一位大哥,然后他告訴我在變量i前面加上一個volatile。果然,代碼運行和我的預期一樣了”。代碼如下
void main() {unsigned char x = 1;while(x){} }void USART1_IRQHandler(void) {x = 0 ; }那么volatile到底是做什么的呢?查閱了幾篇博客,總算是明白了其中的道道。
volatile的本意是“易變的”。因為訪問寄存器要比訪問內存單元快的多,所以編譯器一般都會作減少存取內存的優化,但有可能會讀臟數據。當要求使用volatile聲明變量值的時候,系統總是重新從它所在的內存讀取數據,即使它前面的指令剛剛從該處讀取過數據。精確地說就是,遇到這個關鍵字聲明的變量,編譯器對訪問該變量的代碼就不再進行優化,從而可以提供對特殊地址的穩定訪問;如果不使用valatile,則編譯器將對所聲明的語句進行優化。(簡潔的說就是:volatile關鍵詞影響編譯器編譯的結果,用volatile聲明的變量表示該變量隨時可能發生變化,與該變量有關的運算,不要進行編譯優化,以免出錯)
看兩個例子:
1、如果你的程序是這樣的。
int num = 0 ; num = 1; num = 2;如上,你的編譯器就會去去優化你的代碼,可能被優化成這樣:
int num = 0 ; num = 2;結果“num = 1;”這條指令就丟失了。
但是如果你加上了volatile,你的代碼變成了這樣:
volatile int num = 0 ; num = 1; num = 2;那么你的編譯器就不再會去優化你的代碼,你編譯出來的指令還是三條。
?
2、當你遇到博主上面的情況時,你也應該加上volatile。第二種使用volatile的情況就是,在某個函數中定義的變量可能在函數外面被改變的情況,你就應該加上volatile,保證每次都必須從內存中讀取數據,而不能重復使用放在cache或寄存器中的備份。
這種情況,尤其是在單片機程序,需要在中斷程序中,改變某個變量的時候,用的特別多。
?
3、當然還有其他一些使用volatile的情況,如,存儲器映射的硬件寄存器通常也要加voliate,因為每次對它的讀寫都可能有不同意義。
#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,被這三個定義的變量,都是必須從內存中去讀值的。
?
好,說完了。一句話總結一下,volatile到底有什么用。它的作用就是叫編譯器不要偷懶,去內存中去取值。
?
?
總結
以上是生活随笔為你收集整理的C语言 volatile的作用与使用场景的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: (转)跟我一起写 Makefile(一)
- 下一篇: 基于STM32分析栈、堆、全局区、常量区