在使用 TM4C123GXL 時,我遇到了一個奇怪的行為,我認為這歸因于編譯器。(TI v20.2.5.LTS) 將按位求反函式與等價運算子結合使用時,編譯器似乎沒有正確遵循操作順序。
本質上,您會發現選項#1 將不起作用,即使它應該是正確的(據我所見)也會導致錯誤。但是,選項 #2 將起作用并將結果為真。(據我所知,這與不必要的變數宣告相同)
選項#1(應該有效,但無效)
uint8_t foo = 0x40; // 0100 0000
uint8_t fooinv = 0xBF; // 1011 1111
uint8_t bar = 0x04; // 0000 0100
uint8_t barinv = 0xFB; // 1101 1111
bool valid = true;
valid = (foo == ~fooinv) && valid;
valid = (bar == ~barinv) && valid;
選項#2(額外變數但有效)
uint8_t foo = 0x40; // 0100 0000
uint8_t fooinv = 0xBF; // 1011 1111
uint8_t bar = 0x04; // 0000 0100
uint8_t barinv = 0xFB; // 1101 1111
uint8_t temp1 = ~fooinv;
uint8_t temp2 = ~barinv;
bool valid = true;
valid = (foo == temp1) && valid;
valid = (bar == temp2) && valid;
我懷疑這是因為可能存在某種未解決的資料危害,但我無法確定這里發生了什么。我還沒有反匯編編譯器創建的代碼,但感謝您提供任何幫助。
uj5u.com熱心網友回復:
的行為~在 C 2018 6.5.3.3 4 中指定,其中包括:
... 整數提升在運算元上執行,結果具有提升的型別...
整數促銷轉換uint8_t為int. 因此,在 中,~fooinv, 的值被轉換為。這不會改變值;它仍然是,這是相同的值,只是顯示了更多位。(對于這個答案,我將使用 32-bit ,這在 C 實作中目前很常見。)然后執行按位否定 yield 。這與 , 的值不同,因此當然會產生假(零)。fooinv0xBFint0x000000BFint0xFFFFFF40foo0x40foo == ~fooinv
如果您想計算fooinva中的按位否定uint8_t,您可以簡單地轉換結果:(uint8_t) ~fooinv. 比較結果為foo == (uint8_t) ~fooinv真(一)。
uj5u.com熱心網友回復:
問題是在這些運算式中
valid = (foo == ~fooinv) && valid;
valid = (bar == ~barinv) && valid;
使用整數提升將這樣~fooinv的運算元轉換為 type int。所以實際上你正在處理 value = 0xFFFFFF40。
來自 C 標準(6.5.3.3 一元算術運算子)
4 ~ 運算子的結果是其(提升)運算元的按位補碼(即,當且僅當未設定轉換運算元中的相應位時,結果中的每個位都被設定)。整數提升在運算元上執行,結果具有提升的型別。如果提升的型別是無符號型別,則運算式 ~E 等價于該型別中可表示的最大值減去 E。
所以要得到預期的結果,你應該寫
valid = (foo == ( uint8_t )~fooinv) && valid;
valid = (bar == ( uint8_t )~barinv) && valid;
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/448873.html
