#include <stdio.h>
int main(void)
{
if (sizeof(int) > -1)
printf("True");
else
printf("False");
}
它打印False
。为什么 sizeof() 不返回一个值if
?
sizeof
不是函数,而是运算符。括号不是操作员姓名的一部分。size_t
,这会导致“通常的算术转换”-1
被转换为无符号,在这种情况下它是一个非常大的数字。基本上你是在比较4 > 0xffffffffu
,或者至少是接近的东西。有关详细信息,请参阅此问题。
无符号和有符号整数提升(更准确地说,是“通常的算术转换”)。sizeof
产生一个类型的值size_t
,当与无符号值(即size_t
)比较时,-1 被提升为该类型,并溢出并变得巨大。
无符号整数溢出具有明确定义的行为,将被视为模数2 ^ width
,其中width
是特定无符号整数类型中的位数。因此,如果您有一个 32 位宽的size_t
和int
,例如,您的比较将等同于
if (4 > 4294967295u)
这显然是错误的。
sizeof(int)
and -1
。sizeof(int)
是 类型size_t
,保证为无符号整数。在实践中,size_t
它很可能至少与unsigned int
那里的任何系统一样大。-1
是 类型int
,相当于signed int
。这些状态(C11 6.3.1.8):
...
否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。
否则,两个操作数都转换为与带符号整数类型的操作数类型对应的无符号整数类型。
int
不能适合 a 的所有值size_t
。-1
被转换为无符号整数。在实践中,size_t
它很可能等同于 unsigned int 或 unsigned long。将 -1 存储在此类变量中时发生的任何事情都是实现定义的行为。0xFFFFFFFF
(FF 的数量取决于给定系统上 int 的大小)。4 > 0xFFFFFFFF
评估为假。Sizeof 是一个产生 unsigned long int 的运算符。因此,当您将 unsigned long int 与 -1 进行比较时,它存储为0xffffffff
(int 的大小为 4 个字节)。
-1 默认为有符号整数。但是,与signed int 和unsigned int 相比,编译器将signed int 隐式类型转换为unsigned int。这导致 unsigned -1 大约等于 4.6giga 值。
因此,输出为false
。
只需测试一下,自己看看
#include <stdio.h>
main() {
unsigned int a=4;
int b = -1;
//this is what you're doing
printf("%u vs %u\n", a, (unsigned int)b);
//this is what you want to do instead
printf("%d vs %d\n", (int)a, b);
}