int n = -2147483648;
如此簡單的一句代碼,居然出現了警告?-2147483648是32位int類型可以存儲的最小整型值,為什么會出項警告呢。在VC++6.0控制臺程序下出現如下警告:warning C4146: unary minus operator applied to unsigned type, result still unsigned。在C-Free中出現:c:55: warning: decimal constant is so large that it is unsigned。
上網查了下,發現了原因:
一元負運算符應用于無符號類型,結果仍為無符號類型。無符號類型只能保存非負值,所以一元負(非)應用于無符號類型時通常無意義。操作數和結果都是非負的。
實際上,當程序員試圖表達最小整數值-2147483648 時,發生此問題。該值不能寫為-2147483648,因為表達式處理分兩個步驟:
計算數字2147483648。因為2147483648 大于最大整數值2147483647,所以其類型不是int,而是unsigned int。
將一元負應用于該值,得到無符號結果,該結果碰巧是 2147483648。無符號類型的結果可能導致意外行為。如果在比較中使用該結果,則可使用無符號比較,而不能出現另一個操作數是 int 時。這解釋了下面的示例程序只輸出一行的原因。
預期的第二行為:1 is greater than the most negative int,但未輸出,因為((unsigned int)1) > 2147483648為假。
#include <stdio.h>
main()
{
check(-10);
check(1);
return 0;
}
void check(int i)
{
if (i > -2147483648)
printf("%d is greater than the most negative int\n", i);
}
輸出結果:

上面的解釋省略了一些細節,我來補充下。在if (i > -2147483648)中,由于i為int類型,而-2147483648為unsigned int類型,所有i就會被提升為unsigned int類型,這就是C語言的整型提升。-10提升為unsigned int類型后,其值肯定會大于2147483648,因此第一條語句會打印出來。當把正整數(比如本實驗中的1)提升為unsigned int類型時,其值是不變的,因此肯定比2147483648要小,所有第二條語句不會打印。
那如何來解決這個可惡的警告呢。網上說:可以通過從 Limits.h 使用INT_MIN(一個宏定義) 來避免C4146 警告。INI_MIN宏有如何的魔力,竟然能夠消除這個警告呢。打開源文件一看,原來是這樣:
#define INT_MAX 2147483647
#define INT_MIN (-INT_MAX-1)
哦,原來這樣。因此,我們又可以這樣賦值最小負整數:
int n = -2147483647 - 1;