我知道一個寄存器關鍵字將爲計算值分配一個寄存器,每當我們對變量執行一些計算並基本上不優化代碼時,volatile關鍵字將從內存中讀取值。所以,如果一個變量被分配了這兩個關鍵字,那麼這是否意味着它本質上會是自變量?我無法通過編寫示例代碼來理解行爲。任何人都可以點亮一下嗎?如何在C中註冊「volatile volatile int i」?
回答
在C中,register
存儲類的行爲與auto
存儲類的行爲完全相同,只是如果程序嘗試獲取或使用對象的地址(6.5)需要實現(每5.1.1.3)發佈診斷.3.2,6.7.1)。使用register
作爲編譯器的優化提示通常是毫無意義的,因爲足夠聰明的編譯器可以利用非存儲的對象質量,這當然足夠聰明以跟蹤哪些對象可以被聲明register
;相反,它應該被理解爲代碼質量檢查,程序員不會通過獲取對象的地址而無意中摧毀優化機會。
換句話說,從有效程序中刪除register
關鍵字的所有實例對程序的語義沒有影響;它在這方面與static_assert
類似。
volatile
類型限定符指示訪問(讀取和寫入)對象被認爲是副作用,無法優化。對於一個對象,該對象不限定位置存儲器(即,具有register
存儲類之一),這將是最有用的性能測試存在:
start = time();
for (multiple loops)
register volatile int result = test_function();
stop = time();
elapsed = stop - start;
我很好奇你的示例中的「register volatile」與簡單的'volatile'有什麼不同? – dasblinkenlight
@dasblinkenlight沒有區別,因爲程序是有效的。 – ecatmur
volatile關鍵字的一個更容易理解的視圖是,它告訴編譯器,無論何時指定了變量,編譯器都應該假定該變量可能已被某個其他進程或線程或設備改變。優化時的編譯器可以通過假設如果將變量值加載到寄存器中來消除重複訪問變量,則可以將寄存器中的值作爲該值的當前副本,直到編譯器找到修改該變量的源代碼。 Volatile告訴編譯器這個假設是無效的。 –
volatile
意味着該對象可以這樣的方式改變對編譯器來說是不可預測的,並且register
意味着它的地址不能被採用。
當這個對象實際上是平臺上的一個硬件寄存器時,兩者的結合就非常有意義。一些編譯器(例如gcc)甚至有擴展來修復這個變量到特定的硬件寄存器。
其他一些代碼可能會更改這樣的硬件寄存器,因此編譯器可能會對當前值不做任何處理。在這種情況下,添加const
限定符甚至是有意義的。與海灣合作委員會的擴展E.g
register uint32_t volatile const eax __asm__("eax");
你必須檢查在任何時刻eax
寄存器的工具,但你不能夠意外改變它。
'volatile'也意味着所有對變量的寫入都必須實際發生。 –
@TorKlingberg,你對「寄存器」變量的「寫入」意味着什麼。沒有這種變量的「存儲」模型,因此沒有「讀取」或「寫入」模型。 –
- 1. C#volatile數組項?
- 2. 在C#中使用Volatile關鍵字
- 3. 如何在Swift中聲明volatile變量
- 4. 爲什麼在C++中寄生於'volatile'?
- 5. C中的volatile變量
- 6. volatile boolean
- 7. C++:const volatile的方法
- 8. 在通用C庫中是否有TestAndSet(volatile int * lock)函數?
- 9. C++ volatile成員函數
- 10. *(volatile unsigned int *)的含義0x00 = 0x00;
- 11. 將volatile變量定義爲extern int
- 12. volatile如何實際工作?
- 13. 在C++中 - 是否可以將volatile volatile shared_ptr與nullptr進行比較?
- 14. 是否有任何理由在C中聲明「volatile const」,但在C++中只聲明「volatile」?
- 15. 類型將volatile char轉換爲註冊char類型
- 16. volatile關鍵字
- 17. 在.net中創建註冊表volatile子項是否有更簡單的方法?
- 18. C++中的對象的volatile關鍵字
- 19. 本地volatile變量
- 20. 在C/C++ MUD代碼中asm volatile問題
- 21. 查看vs volatile表?
- 22. 沒有volatile關鍵字
- 23. 如何使用volatile多圖迭代器?
- 24. 方法簽名中'volatile'?
- 25. java中的volatile和threadLocal
- 26. 非volatile變量限制使用C
- 27. 指向易失性數據的指針(*((volatile volatile uint32_t *)0x40000000))
- 28. 關於該volatile關鍵字
- 29. 賦值表達式和volatile
- 30. 爲什麼點對易失性指針(如「volatile int * p」)有用?
什麼平臺和編譯器?我不認爲大多數通用編譯器(例如默認配置的GCC)都會尊重「註冊」。 – Joe
'註冊'必須具備的一個效果是你不能接受一個變量聲明的地址。 –
@Daniel:我不明白你的觀點。不能把變量的地址作爲?你的意思是說它可以被指針訪問嗎? – knightofhorizon