2012-03-29 71 views
57

volatile是告訴編譯器不要優化引用,以便每個讀/寫不使用存儲在寄存器中的值,而是實際訪問內存。我可以理解它對於一些普通變量是有用的,但不明白如何影響指針。爲什麼點對易失性指針(如「volatile int * p」)有用?

volatile int *p = some_addr; 
int a = *p; // CPU always has to load the address, then does a memory access anyway, right? 

如果它被宣佈爲int *p = some_addr,它有什麼區別?

回答

101

形式

volatile int* p; 

的指針是一個指向int編譯器將當作volatile。這意味着編譯器會假定即使源代碼中沒有任何內容表明可能會發生這種情況,但是p指向的變量也可能發生更改。例如,如果我將p設置爲指向一個常規整數,則每次讀取或寫入*p時,編譯器都會意識到該值可能意外發生了變化。

還有一個用例爲volatile int*:如果您聲明intvolatile,那麼你不應該在它與常規int*點。例如,這是一個壞主意:

volatile int myVolatileInt; 
int* ptr = &myVolatileInt; // Bad idea! 

這樣做的原因是,C編譯器不再記得該變量指向由ptrvolatile,所以它可能在寄存器中不正確緩存的*p值。事實上,在C++中,上面的代碼是一個錯誤。相反,你應該寫

volatile int myVolatileInt; 
volatile int* ptr = &myVolatileInt; // Much better! 

現在,編譯器會記住ptr點在volatile int,所以不會(或不應該!)嘗試優化訪問,通過*ptr

最後一個細節 - 您討論的指針是指向volatile int的指針。你也可以這樣做:

int* volatile ptr; 

這是說指針本身volatile,這意味着編譯器不應該嘗試緩存指針在內存或嘗試優化指針值,因爲指針本身可能是由別的東西(硬件,另一個線程等)可以結合在一起,這些得到重新分配,如果你想獲得此獸:

volatile int* volatile ptr; 

這是說,無論是指針和指針可以得到意外更改。編譯器無法優化指針本身,也無法優化指向的內容。

希望這會有所幫助!

+0

我認爲你的意思是「你不應該用普通的int *指向它」 – markgz 2012-03-29 23:52:16

+0

@ markgz-哎呀!對,那是正確的。固定。 – templatetypedef 2012-03-29 23:52:39

+0

我認爲這也是C語言中的一個錯誤,但C編譯器不太可能抱怨類型不匹配。 – 2012-03-29 23:53:27

6

此代碼volatile int *p = some_addr聲明指向volatile int的指針。指針本身不是volatile

在您需要的指針揮發以及整型萬一,你將需要使用:

volatile int * volatile p; 

我不能想到一個情況下,你就需要使用。

+2

例如:I在ISR代碼中使用'volatile uint8_t * volatile pData'來修改指針及其指向的數據。指針由主代碼設置,稍後會讀取指針和數據。 – Christoph 2013-02-24 00:24:12