[英]С typecasting in conditions
有一個簡單的例子:
unsigned a = -5;
int b = 5;
if (a + b <= -1){
...
}
哪種類型會投射a+b
? 要簽名還是不簽名? 是在 C 標准中注明還是由編譯器決定要做什么?
由於通常的算術轉換,如果兩個對象具有相同的等級,則有符號整數類型的對象將轉換為無符號整數類型。
來自 C 標准(6.3.1.8 通常的算術轉換)
否則,如果具有無符號整數類型的操作數的秩大於或等於另一個操作數的類型的秩,則將具有有符號整數類型的操作數轉換為具有無符號整數類型的操作數的類型。
和(6.5.8 關系運算符)
3 如果兩個操作數都是算術類型,則執行通常的算術轉換。
所以在這種情況下
if (a + b <= -1){
兩個操作數a + b
和-1
都被轉換為unsigned int
類型。
也就是說, a
具有unsigned int
類型,然后表達式a + b
也具有unsigned int
類型。 由於表達式a + b
具有unsigned int
類型,因此表達式-1
也將具有 unsigned int 類型( -1
將轉換為unsigned int
類型的unsigned int
)。
因此 if 語句的條件將評估為邏輯true
。
首先,請注意您的術語:
將 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 ;-)
(見隸屬關系簡介)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.