volatile (C++)
類型限定詞,可以用來宣告程式中的物件可以由硬體修改。
語法
volatile declarator ;
備註
您可以使用 /volatile 編譯器參數來修改編譯器解譯此關鍵字的方式。
Visual Studio 會 volatile
根據目標架構以不同的方式解譯 關鍵字。 針對 ARM,如果未 指定 /volatile 編譯器選項,則編譯器會執行如同已指定 /volatile:iso 一樣 。 針對 ARM 以外的架構,如果未 指定 /volatile 編譯器選項,編譯器會執行如同已指定 /volatile:ms 一樣 ;因此,對於 ARM 以外的架構,強烈建議您指定 /volatile:iso ,並在處理跨執行緒共用的記憶體時,使用明確的同步處理基本類型與編譯器內建函式。
您可以使用 volatile
限定詞來存取非同步進程所使用的記憶體位置,例如插斷處理常式。
當 在具有 __restrict 關鍵字的 變數上使用 時 volatile
, volatile
會優先使用 。
struct
如果成員標示為 volatile
,則會 volatile
傳播至整個結構。 如果結構沒有可以使用一個指令在目前架構上複製的長度, volatile
該結構可能會完全遺失。
如果下列其中一個條件成立,關鍵字 volatile
可能會對欄位沒有任何影響:
volatile 欄位長度超過可透過單一指令複製到目前架構的大小上限。
最外層包含
struct
的長度,如果它是可能巢狀struct
的成員,則超過可以使用一個指令在目前架構上複製的大小上限。
雖然處理器不會重新排序無法快取的記憶體存取,但不可快取的變數必須標示為 volatile
,以確保編譯器不會重新排序記憶體存取。
宣告為 volatile
的物件不會用於特定優化,因為它們的值隨時都可以變更。 即使先前指令要求相同物件的值,再次被要求時,系統一定會讀取暫時性物件目前的值。 此外,物件的值會在指派時立即被寫入。
ISO 一致性
如果您熟悉 C# volatile 關鍵字,或熟悉舊版 Microsoft C++ 編譯器 (MSVC) 的行為 volatile
,請注意 C++11 ISO Standard volatile
關鍵字不同,且在指定 /volatile:iso 編譯器選項時 ,MSVC 支援。 (對於 ARM 系統來說,預設為指定)。 volatile
C++11 ISO Standard 程式碼中的 關鍵字僅用於硬體存取;請勿用於執行緒間通訊。 針對執行緒間通訊,請使用 C++ 標準程式庫的 std::atomic < T > 等 機制。
符合 ISO 標準的結尾
Microsoft 特定的
當使用 /volatile:ms 編譯器選項時,預設為以 ARM 以外的架構為目標時,編譯器會產生額外的程式碼,以在動態物件的參考之間維持排序,同時維護對其他全域物件的參考順序。 特別是:
暫時性物件的寫入 (也稱為暫時性寫入) 有 Release 語義,也就是說,在指令序列中暫時性物件寫入之前的全域或靜態物件參考,會在已編譯二進位檔中的暫時性寫入之前發生。
暫時性物件的讀取 (也稱為暫時性讀取) 有 Acquire 語義,也就是說,在指令序列中揮發性記憶體讀取之後的全域或靜態物件參考,會在已編譯二進位檔中的暫時性讀取之後發生。
這可讓暫時性物件用於多執行緒應用程式的記憶體鎖定和記憶體釋放。
注意
當它依賴使用 /volatile:ms 編譯器選項時所提供的增強保證時 ,程式碼是不可移植的。
END Microsoft 特定的
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應