一切源于《深入理解计算机系统(第三版)》中第二章的一个小问题……
C语言的有符号整型最小值定义
为什么要用 (-INT_MAX - 1)呢?为什么不直接用-2147483648?
因为-2147483648是由字面值2147483648加上单目运算符“-”组成的。负号和数字并非是一体的,编译器会先解析数字,再给数字施加负号运算。
这样一来,因为int不足以表示字面值2147483648,所以字面值2147483648的类型会是long,最终导致-2147483648的类型也是long。
如果用一个long去描述int的最小值,这合理吗(笑)?
为什么不能用0x80000000?
对于C,所有整型字面值都是非负数(但字面值所属的数据类型可以是有符号类型)。对于“-1”这种情况,负号运算符“-”和字面值“1”是分离的。
There are no negative integer literals. Expressions such as -1 apply the unary minus operator to the value represented by the literal, which may involve implicit type conversions.
正因如此,0x80000000相当于2147483648,而不是按照补码解释的-2147483648。2147483648超过了int的范围,被扩大为unsigned int。
为什么被扩大为unsigned int而不是long?
因为0x80000000是16进制整型无后缀字面值,这种字面值的类型匹配顺序为int->unsigned int->long…见下表no suffix - other bases对应的单元格~
因此字面值0x80000000的类型为unsigned int。
如果我们直接把字面常量写作十进制无后缀数2147483648,那么按照no suffix - decimal bases单元格所描述的,这种字面值的类型匹配顺序为int->long->unsigned long(C99之前)/long long(C99及其以后)。
因此字面值2147483648的类型为long。