C語言中volatile關鍵字的學習

2021-08-13 17:30:22 字數 1458 閱讀 5649

背景:

最近在學習stm32l152晶元,看到對應的hal庫中經常見到volatile關鍵字,對該關鍵字不是很明白,所以總結一下該關鍵字的使用。

學習內容記錄:

volatile單詞的意思:易變的。在學習volatile之前,先簡單理解一下編譯器的優化。如下例:

uint8_t i;

i=0;

i=1;

i=2;

這段程式中,編譯器可能會認為只有i=2;這句才有意思,把i儲存在某個暫存器中,當要使用i時從這個暫存器讀取資料,若i由於中斷或多執行緒而使i的變數位址的資料改變,那麼讀取i的值可能就不一致,進而導致程式執行錯誤。

volatile關鍵字就可以避免上述錯誤的出現,提高**的魯棒性,也體現了程式設計師必備的一種基本功。

volatile提醒編譯器它後面所定義的變數隨時都有可能改變,因此編譯後的程式每次需要儲存或讀取這個變數的時候,都會直接從變數位址中讀取資料。如果沒有volatile關鍵字,則編譯器可能優化讀取和儲存,可能暫時使用暫存器中的值,如果這個變數由別的程式更新了的話,將出現不一致的現象。

下面以stm32的hal庫中的例子繼續講解volatile關鍵字,如定時器結構體中暫存器的定義

繼續go to definition of '_io'如下;

可以看到_io定義語句中後面的關鍵字,指明在暫存器的對映中,暫存器中的資料也是易改變的。

下面以乙個例項說明volatile關鍵字的使用。

uint8_t flag;

int main()

while(1)

void tim_irqhandler(void)

上述函式的功能是當發生定時器的中斷時,把flag置1,while(1)迴圈中檢測到flag 的值改變為1,便會去執行自己的程式do();

需要注意的是,沒有volatile也可能能正常執行,但是可能修改了編譯器的優化級別之後就又不能正常執行了。因此經常會出現debug版本正常,但是release版本卻不能正常的問題。所以為了安全起見,只要是等待別的程式修改某個變數的話,就加上volatile關鍵字。修改後的程式如下:

volatile uint8_t flag;

int main()

while(1)

void tim_irqhandler(void)

總結:

volatile 關鍵字提醒編譯器定義的變數是易變的,編譯後的程式每次需要儲存或讀取該變數時,會直接從變數位址讀取資料。在中斷或多執行緒中使用volatile關鍵字可以避免不同優化等級時程式出錯,提高程式的魯棒性。

c語言中volatile關鍵字

volatile關鍵字是一種型別修飾符,用它宣告的型別變數表示可以被某些編譯器未知的因素更改 比如 作業系統 硬體或者其它執行緒等。遇到這個關鍵字宣告的變數,編譯器對訪問該變數的 就不再進行優化,從而可以提供對特殊位址的穩定訪問。使用該關鍵字的例子如下 int volatile nvint 當要求使...

C語言中volatile關鍵字

一 前言 程式的優化 1 硬體級別上的優化 a.由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。b.在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。2 軟...

C語言中volatile關鍵字

1.編譯器優化介紹 由於記憶體訪問速度遠不及cpu處理速度,為提高機器整體效能,在硬體上引入硬體快取記憶體cache,加速對記憶體的訪問。另外在現代cpu中指令的執行並不一定嚴格按照順序執行,沒有相關性的指令可以亂序執行,以充分利用cpu的指令流水線,提高執行速度。以上是硬體級別的優化。再看軟體一級...