40
#include <stdio.h>
int main(void)
{
    if (sizeof(int) > -1)
        printf("True");
    else
        printf("False");
}

它打印False。为什么 sizeof() 不返回一个值if

4

5 回答 5

55
  1. sizeof不是函数,而是运算符。括号不是操作员姓名的一部分。
  2. 它失败了,因为生成的值具有无符号类型size_t,这会导致“通常的算术转换”-1被转换为无符号,在这种情况下它是一个非常大的数字。

基本上你是在比较4 > 0xffffffffu,或者至少是接近的东西。有关详细信息,请参阅此问题

于 2013-06-25T09:32:02.747 回答
24

无符号和有符号整数提升(更准确地说,是“通常的算术转换”)。sizeof产生一个类型的值size_t,当与无符号值(即size_t)比较时,-1 被提升为该类型,并溢出并变得巨大。

无符号整数溢出具有明确定义的行为,将被视为模数2 ^ width,其中width是特定无符号整数类型中的位数。因此,如果您有一个 32 位宽的size_tint,例如,您的比较将等同于

if (4 > 4294967295u)

这显然是错误的。

于 2013-06-25T09:32:41.263 回答
13
  • if 语句中 > 运算符的操作数是sizeof(int)and -1
  • sizeof(int)是 类型size_t,保证为无符号整数。在实践中,size_t它很可能至少与unsigned int那里的任何系统一样大。
  • -1是 类型int,相当于signed int
  • 不会发生整数提升,因为两个操作数都是足够大的整数类型。
  • 然后根据正式称为通常算术转换的 C 规则平衡两个操作数。

这些状态(C11 6.3.1.8):

...

否则,如果有符号整数类型的操作数的类型可以表示无符号整数类型的操作数的所有值,则将无符号整数类型的操作数转换为有符号整数类型的操作数的类型。

否则,两个操作数都转换为与带符号整数类型的操作数类型对应的无符号整数类型。

  • 上述后者将发生,因为 a (signed)int不能适合 a 的所有值size_t
  • 因此-1被转换为无符号整数。在实践中,size_t它很可能等同于 unsigned int 或 unsigned long。将 -1 存储在此类变量中时发生的任何事情都是实现定义的行为。
  • 在二进制补码计算机(世界上所有计算机的 99.9%)上,-1 将被解释为0xFFFFFFFF(FF 的数量取决于给定系统上 int 的大小)。
  • 4 > 0xFFFFFFFF评估为假。
于 2013-06-25T09:51:59.563 回答
2

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

于 2017-01-07T12:25:32.930 回答
1

只需测试一下,自己看看

#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);
}
于 2013-06-25T13:31:40.143 回答