unsigned long 0 <-1?

nai*_*oon 8 c

我不懂这个!

#include <stdio.h>

int 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");
}
Run Code Online (Sandbox Code Playgroud)

这导致:

 s1 < s2-1
Run Code Online (Sandbox Code Playgroud)

要么两者都失败,要么两者都失败.我用gcc 4和4.2试过这个

cod*_*nix 13

我不确定,但我怀疑表达式t2-1自动扩展为int值.我这里没有c标准确切的转换规则是什么,但我相信小于int的类型会自动加宽.

  • +1,在算术表达式中,类型(有符号/无符号)short和(signed/unsigned /)char的对象被*提升为*. (3认同)

Mic*_*urr 12

C语言为许多操作员执行"常用算术转换" - 转换在C99标准的6.3.1.8中概述.对于整体操作数,会执行首次促销,这就是造成问题的原因.6.3.1.1(算术操作数/布尔值,字符和整数)中概述了这些促销,其中包括:

如果int可以表示原始类型的所有值,则该值将转换为int; 否则,它将转换为unsigned int.这些被称为整数促销.整数促销不会更改所有其他类型.

促销仅应用于具有等级小于intunsigned int(或位域)的整数类型的对象或表达式.

所以在你的经历中:

t1 < t2-1 
Run Code Online (Sandbox Code Playgroud)

即使变量unsigned short被提升为int,因为在您的平台上int可以表示所有的值unsigned short.因此,使用int类型来计算表达式,并且不会发生下溢 - t2-1表达式的一部分最终为负1.

在表达式中:

s1 < s2-1
Run Code Online (Sandbox Code Playgroud)

unsigned long类型不促进,因为它们具有比较高的"等级" int/ unsigned int,所以表达式是使用无符号算术运算(与来自减法下溢)来评价,并且s2-1子表达式的计算结果为一个非常大的数量,而不是负1.

正如评论中指出的那样,如果平台已经int实现为16位类型(例如允许 - 例如MS-DOS),则促销unsigned shortunsigned int代替int,因为int无法表示所有值的unsigned short(unsigned short必须至少为16位).在这种情况下,两个if语句都会评估为真.