1. 程式人生 > >關鍵字volatile有什麼含意 並給出三個不同的例子

關鍵字volatile有什麼含意 並給出三個不同的例子

volatile的作用是: 作為指令關鍵字,確保本條指令不會因編譯器的優化而省略,且要求每次直接讀值,即不是從暫存器裡取備份值,而是去該地址記憶體儲存的值.

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

XBYTE[2]=0x55;

XBYTE[2]=0x56;

XBYTE[2]=0x57;

XBYTE[2]=0x58;

對外部硬體而言,上述四條語句分別表示不同的操作,會產生四種不同的動作,但是編譯器卻會對上述四條語句進行優化,認為只有XBYTE[2]=0x58(即忽略前三條語句,只產生一條機器程式碼)。如果鍵入volatile,編譯器會逐一的進行編譯併產生相應的機器程式碼(產生四條程式碼).下面是volatile變數的幾個例子:

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

2) 一箇中斷服務子程式中會訪問到的非自動變數;

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

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

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

答案:

1) 是的。一個例子是隻讀的狀態暫存器(計算機系統的核心部件——運算器的一部分,狀態暫存器用來存放兩類資訊:一類是體現當前指令執行結果的各種狀態資訊(條件碼),如有無進位(CF位)等;另一類是存放控制資訊(PSW:程式狀態字暫存器),如允許中斷(IF位)等)。它是volatile因為它可能被意想不到地改變。它是const因為程式不應該試圖去修改它。沒問題,const和volatile這兩個型別限定符不矛盾。const表示(執行時)常量語義:被const修飾的物件在所在的作用域無法進行修改操作,編譯器對於試圖直接修改const物件的表示式會產生編譯錯誤。volatile表示“易變的”,即在執行期物件可能在當前程式上下文的控制流以外被修改(例如多執行緒中被其它執行緒修改;物件所在的儲存器可能被多個硬體裝置隨機修改等情況):被volatile修飾的物件,編譯器不會對這個物件的操作進行優化。一個物件可以同時被const和volatile修飾,表明這個物件體現常量語義,但同時可能被當前物件所在程式上下文意外的情況修改。

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

是的。儘管這並不很常見。一個例子是當一箇中斷服務子程式修該一個指向一個buffer的指標時。

3) 下面的函式有什麼錯誤:

intsquare(volatile int *ptr)

{

  return *ptr *  *ptr;

}

這段程式碼的目的是用來返指標*ptr指向值的平方,但是,由於*ptr指向一個volatile型引數,編譯器將產生類似下面的程式碼:

intsquare(volatile int *ptr)

{

inta,b;

a =*ptr;

b =*ptr;

returna * b;

}

由於*ptr的值可能被意想不到地該變,因此a和b可能是不同的。結果,這段程式碼可能返不是你所期望的平方值!正確的程式碼如下:

longsquare(volatile int *ptr)

{

int a;

a =*ptr;

returna * a;

}