1.易變性
1.1概念
編譯器對volatile修飾的變量,當要讀取這個變量時,任何情況下都會從內存中讀取,而不會從寄存器緩存中讀取(因為每次都從內存中讀取體現出變量的“易變”)
1.2測試代碼(VS 2008編譯出來的Release版本)
1)非volatile變量
b = a + 1;這條語句,對應的匯編指令是:lea ecx, [eax + 1]。由於變量a,在前一條語句a = fn(c)執行時,被緩存在了寄存器eax中,因此b = a + 1;語句,可以直接使用仍舊在寄存器eax中的內容,來進行計算,對應的也就是匯編:[eax + 1]
2)volatile變量
與測試用例一唯一的不同之處,是變量a被設置為volatile屬性,一個小小的變化,帶來的是匯編代碼上很大的變化。a = fn(c)執行后,寄存器ecx中的a,被寫回內存:mov dword ptr [esp+0Ch], ecx。然后,在執行b = a + 1;語句時,變量a有重新被從內存中讀取出來:mov eax, dword ptr [esp + 0Ch],而不再直接使用寄存器ecx中的內容
2.不可優化性
2.1概念
編譯器不會對volatile修飾的變量進行任何優化
2.2測試代碼(VS 2008編譯出來的Release版本)
1)非volatile變量
在這個用例中,非volatile變量a,b,c全部被編譯器優化掉了 (optimize out),因為編譯器通過分析,發覺a,b,c三個變量直接用立即數替換,不必存在內存中。最后的匯編代碼相當簡介,高效率
2)volatile變量
在這個用例中,a、b、c三個變量,都是volatile變量。在匯編語言中,這三個變量存到了內存中,在使用a、b、c時需要將三個變量從內存讀入到寄存器之中,然后再調用printf()函數
3.順序性
1)程序的亂序優化:保證一段代碼的輸出結果的前提下,將各條代碼的實際執行順序進行優化調整
volatile變量與volatile變量間代碼的順序,編譯器不會進行亂序優化,但是volatile變量與非volatile變量代碼的順序,編譯器不保證順序,可能會進行亂序優化
3.2測試代碼
參考資料: