我不懂这个!
#includeint main() { unsigned short t1 = 0, t2 = 0; if( t1 < t2-1 ) printf(" t1 < t2-1\n"); unsigned long s1 = 0, s2 = 0; if( s1 < s2-1 ) printf(" s1 < s2-1\n"); }
这导致:
s1 < s2-1
要么两者都失败,要么两者都失败.我用gcc 4和4.2试过这个
我不确定,但我怀疑表达式t2-1自动扩展为int值.我这里没有c标准确切的转换规则是什么,但我相信小于int的类型会自动加宽.
C语言为许多操作员执行"常用算术转换" - 转换在C99标准的6.3.1.8中概述.对于整体操作数,会执行首次促销,这就是造成问题的原因.6.3.1.1(算术操作数/布尔值,字符和整数)中概述了这些促销,其中包括:
如果int可以表示原始类型的所有值,则该值将转换为int; 否则,它将转换为unsigned int.这些被称为整数促销.整数促销不会更改所有其他类型.
促销仅应用于具有等级小于int
和unsigned int
(或位域)的整数类型的对象或表达式.
所以在你的经历中:
t1 < t2-1
即使变量unsigned short
被提升为int,因为在您的平台上int
可以表示所有的值unsigned short
.因此,使用int
类型来计算表达式,并且不会发生下溢 - t2-1
表达式的一部分最终为负1.
在表达式中:
s1 < s2-1
的unsigned long
类型不促进,因为它们具有比较高的"等级" int
/ unsigned int
,所以表达式是使用无符号算术运算(与来自减法下溢)来评价,并且s2-1
子表达式的计算结果为一个非常大的数量,而不是负1.
正如评论中指出的那样,如果平台已经int
实现为16位类型(例如允许 - 例如MS-DOS),则促销unsigned short
将unsigned int
代替int
,因为int
无法表示所有值的unsigned short
(unsigned short
必须至少为16位).在这种情况下,两个if
语句都会评估为真.