C語言中的volatile

2021-08-09 07:57:13 字數 2685 閱讀 5817

volatile是乙個型別

修飾符(type specifier),就像大家更熟悉的const一樣,它是被設計用來修飾被不同執行緒訪問和修改的變數。

volatile

的作用是作為指令

關鍵字,確保本條指令不會因

編譯器的優化而省略,且要求每次

每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。作用

簡單地說就是防止編譯器對**進行優化。比如如下程式:

1

2

3

4

xbyte[2]=0x55;

xbyte[2]=0x56;

xbyte[2]=0x57;

xbyte[2]=0x58;

對外部硬體而言,上述四條語句分別表示不同的操作,會產生四種不同的動作,但是編譯器卻會對上述四條語句進行優化,認為只有xbyte[2]=0x58(即忽略前三條語句,只產生一條機器**)。如果鍵入

volatile

,則編譯器會逐一地進行編譯並產生相應的機器**(產生四條**)應用

精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在

暫存器裡的備份。下面是volatile變數的幾個例子:

1)並行裝置的硬體暫存器(如:狀態暫存器)

2)乙個中斷服務子程式中會訪問到的非自動變數(non-automatic variables)

3)多執行緒應用中被幾個任務共享的變數

這是區分c程式設計師和

嵌入式系統程式設計師的最基本的問題:嵌入式系統程式設計師經常同硬體、中斷、rtos等等打交道,所有這些都要求使用volatile變數。不懂得volatile內容將會帶來災難。

假設被面試者正確地回答了這個問題(嗯,懷疑是否會是這樣),我將稍微深究一下,看一下這傢伙是不是真正懂得volatile完全的重要性。

1)乙個引數既可以是const還可以是volatile嗎?解釋為什麼。

2)乙個指標可以是volatile 嗎?解釋為什麼。

3)下面的函式被用來計算某個整數的平方,它能實現預期設計目標嗎?如果不能,試回答存在什麼問題:

1

2

3

4

intsquare(volatileint*ptr)

下面是答案:

1)是的。乙個例子是唯讀的

狀態暫存器。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。

2)是的。儘管這並不很常見。乙個例子是當乙個中斷服務子程式修改乙個指向乙個buffer的

指標時。

3)這段**是個惡作劇。這段**的目的是用來返指標*ptr指向值的平方,但是,由於*ptr指向乙個volatile型引數,

編譯器將產生類似下面的**:

1

2

3

4

5

6

7

intsquare(volatileint* &ptr)//這裡引數應該申明為引用,不然函式體裡只會使用副本,外部沒法更改

由於*ptr的值可能在兩次取值語句之間發生改變,因此a和b可能是不同的。結果,這段**可能返回的不是你所期望的平方值!正確的**如下:

1

2

3

4

5

6

longsquare(volatileint*ptr)

講講個人理解:

關鍵在於兩個地方:

⒈ 編譯器的優化(請高手幫我看看下面的理解)

在本次執行緒內,當讀取乙個變數時,為提高訪問速度,編譯器優化時有時會先把變數讀取到乙個暫存器中;以後再取變數值時,就直接從暫存器中取值;

當變數值在本執行緒裡改變時,會同時把變數的新值copy到該暫存器中,以便保持一致

當變數在因別的執行緒等而改變了值,該暫存器的值不會相應改變,從而造成應用程式讀取的值和實際的變數值不一致

當該 暫存器在因別的執行緒等而改變了值,原變數的值不會改變,從而造成應用程式讀取的值和實際的變數值不一致

舉乙個不太準確的例子:

發薪資時,會計每次都把員工叫來登記他們的銀行卡號;一次會計為了省事,沒有即時登記,用了以前登記的銀行卡號;剛好乙個員工的銀行卡丟了,已掛失該銀行卡號;從而造成該員工領不到工資

員工 -- 原始變數位址

銀行卡號 -- 原始變數在暫存器的備份

⒉ 在什麼情況下會出現

1)並行裝置的硬體暫存器

2)乙個中斷服務子程式中會訪問到的非自動變數(non-automatic variables)

3)多執行緒應用中被幾個任務共享的變數

C語言中的volatile

c中 volatile 作用 volatile單詞的意思是易變的,不確定的。在c中,被 volatile 修飾的變數,表示 1 該變數的值是可變的,可能隨時在程式外部被改變 2 使用該變數的時候,必須每次從該變數所在的位址所指的記憶體去讀,不能把它放在暫存器或者 cache 中重複訪問,可以保證對特...

C語言中的volatile

關鍵字volatile 有什麼含意 並給出三個不同的例子。乙個定義為volatile 的變數是說這變數可能會被意想不到地改變,這樣,編譯器就不會去假設這個變數的值了。精確地說就是,優化器在用到這個變數時必須每次都小心地重新讀取這個變數的值,而不是使用儲存在暫存器裡的備份。下面是 volatile 變...

詳解c語言中的volatile

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