3
#include <stdio.h>
int main(void)
{
    printf("%d", sizeof(signed int) > -1);
    return 0;
}

结果为 0(假)。怎么会这样?我使用的是 64 位 ubuntu linux,所以结果应该是 (4 > -1) => 1 => True。

4

3 回答 3

10

问题是sizeof运算符返回一个无符号数量 ( size_t)。所以比较提升-1为无符号,这使它看起来像一个非常大的数字。

你可以试试:

printf("%d", ((int)sizeof(signed int)) > -1);
于 2012-04-15T19:29:33.313 回答
8

sizeof(signed int)有 type size_t,这是一个无符号类型。当您在有符号值和无符号值之间进行比较时[并且无符号值的类型至少与有符号值的类型一样大],有符号值在比较之前转换为无符号值。此转换导致-1成为无符号类型的最大可能值。换句话说,就像你写的

#include <limits.h>
/* ... */
printf("%d", sizeof(signed int) > SIZE_MAX);

当你犯这个错误时,你可以让 gcc 发出警告,但默认情况下它不是打开的,甚至在-Wall: you need-Wextra或更具体地说是-Wsign-compare. (这个警告产生很多误报,但我认为打开新代码很有用。)

于 2012-04-15T19:30:40.377 回答
5

整数促销

C中有许多隐式转换,特别有助于理解所谓的“通常的算术转换”,其中包括所谓的整数提升1

实际的规则有点复杂,但是,简化后,当运算符具有不同类型的操作数时,所有标量类型都会自动转换。转换首先获取较低级别的操作数并将其转换为较高级别的类型。然后,如果只有一个操作数是有符号的,它将被转换为无符号的,除非具有符号类型的操作数更大并且可以表示所有无符号类型的值。您的示例并非如此,因为 size_t 几乎总是与 int 一样大或更大。

最后,在几乎所有机器上,-1 都设置了所有位,当被视为无符号时,它是一个非常大的数字。


1. ISO/IEC 9899:1999 ("C99") 6.3 转换

于 2012-04-15T19:35:12.457 回答