簡體   English   中英

有些奇怪的C ++代碼

[英]slightly weird C++ code

對不起,如果這很簡單,我的C ++就生銹了。

這是做什么的? 據我所知,沒有任何分配或函數調用。 在我繼承的一些代碼中,這個代碼模式重復了很多次。 如果重要的是嵌入式代碼。

*(volatile UINT16 *)&someVar->something;

編輯:從那里繼續,以下附加代碼是否確認了希思的懷疑? (完全來自代碼,包括重復,除了名稱已被更改以保護無辜者)

if (!WaitForNotBusy(50)) 
    return ERROR_CODE_X;

*(volatile UINT16 *)& someVar->something;

if (!WaitForNotBusy(50)) 
    return ERROR_CODE_X;

*(volatile UINT16 *)& someVar->something;
x = SomeData;

這是嵌入式編程中相當常見的習慣用法(盡管它應該封裝在一組函數或宏中),其中需要訪問設備寄存器。 在許多體系結構中,設備寄存器被映射到存儲器地址,並且像任何其他變量一樣被訪問(盡管在固定地址處 - 可以使用指針,或者鏈接器或編譯器擴展可以幫助修復地址)。 但是,如果C編譯器沒有看到對變量訪問的副作用,它可以將其優化 - 除非變量(或用於訪問變量的指針)被標記為volatile。

所以表達;

*(volatile UINT16 *)&someVar->something;

將從存儲在someVar指針中的地址發出一些16位讀取(由something結構元素的偏移量提供)。 由於volatile關鍵字,編譯器將發生此讀取並且無法對其進行優化。

請注意,某些器件寄存器即使只是簡單地讀取它們也會執行某些功能 - 即使沒有使用其他數據也是如此。 這在狀態寄存器中非常常見,其中在讀取指示特定位中的錯誤狀態的寄存器之后可能清除錯誤條件。

這可能是使用volatile關鍵字的常見原因之一。

我認為作者的意圖是讓編譯器在這些點上發出內存障礙 通過評估volatile的表達式結果,對編譯器的指示是該表達式不應該被優化掉,並且應該“實例化”訪問每個行的易失性位置(​​內存障礙,優化限制)的語義。習語出現了。

這種類型的習慣用法可以“封裝”在預處理器宏( #define )中,以防另一個編譯具有不同的方式來產生相同的效果。 例如,具有直接編碼讀取或寫入內存屏障能力的編譯器可能使用內置機制而不是此習慣用法。 在宏中實現此類代碼可以在整個代碼庫中更改方法。

編輯:用戶sharth有一個很好的觀點,如果此代碼在指針的地址是物理地址而不是虛擬地址(或映射到特定物理地址的虛擬地址)的環境中運行,那么執行此讀取操作可能會導致一些在外圍設備上的動作。

所以這是一個很長的鏡頭。

如果該地址指向FPGA或其他設備上的存儲器映射區域,那么當您讀取該地址時,該設備可能實際上正在執行某些操作。

通常這是錯誤的代碼。

在C和C ++中,volatile意味着很少,並且不提供隱式內存屏障。 所以這段代碼完全錯了,你寫的是

memory_barrier();
*(volatile UINT16 *)&someVar->something;

這只是糟糕的代碼。

Expenation: volatile不會變化原子!

里德這篇文章: http//www.mjmwired.net/kernel/Documentation/volatile-considered-harmful.txt

這就是為什么volatile幾乎永遠不會在正確的代碼中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM