繁体   English   中英

if 语句中的 sizeof() 运算符

[英]sizeof() operator in if-statement

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

它打印False 为什么 sizeof() 不在if返回值?

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

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

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

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

if (4 > 4294967295u)

这显然是错误的。

  • if 语句中 > 运算符的操作数是sizeof(int)-1
  • sizeof(int)size_t类型,它保证是一个无符号整数。 实际上,在任何系统上, size_t很可能至少与unsigned int一样大。
  • -1int类型,它等价于signed int
  • 没有整数提升发生,因为两个操作数都是足够大的整数类型。
  • 然后根据正式称为通常算术转换的 C 规则平衡两个操作数。

这些状态(C11 6.3.1.8):

...

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

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

  • 上面的后者将会发生,因为(有符号的) int不能适合size_t所有值。
  • 因此-1被转换为无符号整数。 实际上, size_t很可能相当于 unsigned int 或 unsigned long。 在这样的变量中存储 -1 时发生的任何事情都是实现定义的行为。
  • 在二进制补码计算机(世界上所有计算机的 99.9%)上,-1 将被解释为0xFFFFFFFF (FF 的数量取决于给定系统上 int 的大小)。
  • 4 > 0xFFFFFFFF评估为假。

Sizeof 是一个运算符,它产生一个 unsigned long int。 因此,当您将 unsigned long int 与 -1 进行比较时,它存储为0xffffffff (int 的大小为 4 个字节)。

-1 默认是有符号整数。 但是,在有符号整型和无符号整型之间进行比较时,编译器将有符号整型隐式转换为无符号整型。 这导致无符号 -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);
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM