有一個簡單的例子:
unsigned a = -5;
int b = 5;
if (a b <= -1){
...
}
將投射到哪種型別a b?要簽名還是不簽名?是在 C 標準中注明還是由編譯器決定要做什么?
uj5u.com熱心網友回復:
由于通常的算術轉換,如果兩個物件具有相同的等級,則有符號整數型別的物件將轉換為無符號整數型別。
來自 C 標準(6.3.1.8 通常的算術轉換)
否則,如果具有無符號整數型別的運算元的秩大于或等于另一個運算元的型別的秩,則將具有有符號整數型別的運算元轉換為具有無符號整數型別的運算元的型別。
和(6.5.8 關系運算子)
3 如果兩個運算元都是算術型別,則執行通常的算術轉換。
所以在這種情況下
if (a b <= -1){
兩個運算元a b和-1都被轉換為型別unsigned int。
即a具有unsigned intthen型別,運算式a b也具有 type unsigned int。由于運算式a b具有型別unsigned intthen 并且運算式-1也將具有 unsigned int 型別(-1將轉換為該型別的最大值unsigned int)。
因此 if 陳述句的條件將評估為邏輯true.
uj5u.com熱心網友回復:
首先,請注意您的術語:
將 a b 投射到哪種型別?
強制轉換是顯式轉換(例如(int)(a))...這是隱式轉換!
但是,C 不是一種很棒的語言嗎...
考慮:
unsigned a = -5;
當將負數分配給無符號變數時,任何合理定義的語言都會引發錯誤......
進一步考慮( unsigned int signed int ):OP 不是第一個,也不會是最后一個,因為 C 語言中的隱式型別提升而感到困惑——其中一些甚至比這更不明顯......答案是這將導致一個unsigned int(無符號 有符號 = 無符號)。
然后是潛在的海森蟲(和/或可能是薛定諤蟲):
if ( unsigned int <= -1 )
根據定義,無符號整數不能小于零,因此結果 IF子句是不可到達的,并且很可能被優化掉。然而,-1將實際上被提升到一個unsigned integer作為UINT_MAX,因此這成為if ( unsigned int <= UINT_MAX ),這當然是永遠true的,你必須無條件的條件。
當然,您可能并不真正關心這是無條件正確、無條件錯誤還是錯誤答案......
但大多數時候,這很重要……那么,你如何保護自己?
MISRA C 引入了基本型別模型的概念,其中包含保護您免受意外型別轉換的指南 - 本書的第 8.10 節(包括一些規則)以及兩個附錄。
編輯: <=不僅僅是<按照 OP ;-)
(見隸屬關系簡介)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/331914.html
