为什么32位程序的结果与64位程序的结果不同?

Ste*_*n.W 8 c

我正在进行整数字节级表示的赋值.我写了一个小程序:

e1.c

int main(void) {
    printf("%d\n", -2147483648 < 2147483647);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

当我使用C89标准编译32位版本的可执行文件时,使用该命令gcc e1.c -m64 -std=c89 -g -O0 -o e1,它按预期工作:它打印0指示C编译器将值2147483648视为unsigned int,因此它将表达式的其余部分转换为unsigned int.但奇怪的是,这种关系并不适用于打印的64位版本1.

有谁能解释一下?

Cor*_*lks 10

C89规范如下:

整数常量的类型是相应列表中可以表示其值的第一个.无后缀十进制:int, long int,unsigned long int,[...]

因此,文字的类型2147483648取决于大小int,longunsigned long分别.假设它int是32位,因为它在许多平台上(在您的平台上可能就是这种情况).

在32位平台上,通常long是32位.因此,类型2147483648将是unsigned long.

在64位平台上,通常long是64位(尽管某些平台,如MSVC,仍将使用32位long).因此,类型2147483648将是long.

这会导致你看到的差异.在一个案例中,你是在否定一个unsigned long,而在另一个案例中,你是在否定一个long.

在32位平台上,-2147483648求值为2147483648(使用unsigned long类型).因此得到的比较是2147483648 < 2147483647,评估为0.

在64位平台上,-2147483648求值为-2147483648(使用long类型).因此得到的比较是-2147483648 < 2147483647,评估为1.

  • 同样有趣的是,在C11中,未加十进制的十进制常量是`int`,`long int`和**`long long int`**.似乎没有转换为`unsigned long int`了. (2认同)
  • @ user694733:正确.C89中不存在"long long".在C99中添加时,规则已更改.C11保持了与C99相同的行为. (2认同)