看似合理的程式碼卻輸出 the bug is out!:
int array[] = {23, 34, 12, 17, 204, 99, 16};
#define TOTAL_ELEMENTS (sizeof(array)/sizeof(array[0]))
int main() {
int d = -1;
if (d <= (TOTAL_ELEMENTS - 2)) {
printf("d <= TOTAL_ELEMENTS-2\n");
} else {
printf("the bug is out!\n"); // 實際執行這一行
}
return 0;
}
sizeof 回傳 size_t(無號整數),故 TOTAL_ELEMENTS 為 unsigned int。TOTAL_ELEMENTS - 2 仍為無號型別。<= 觸發 整數提升:有號 d 轉換為無號 unsigned int。-1 轉為無號後變成 UINT_MAX(4294967295),遠大於 5,條件判斷為假。// 方案一:強制轉型
if (d <= (int)(TOTAL_ELEMENTS - 2))
// 方案二:變數改為 size_t
size_t d = 0; // 避免負值
// 方案三:分開判斷
if (d >= 0 && d <= (int)(TOTAL_ELEMENTS - 2))
int / long。-Wsign-compare (GCC/Clang) 可在編譯期捕捉此類問題。《C 專家編程》第 1 章詳細論述此陷阱;CERT C 編碼標準 INT02-C「理解整數轉換規則」提供規範化指導。