简体   繁体   English

if 语句中的 sizeof() 运算符

[英]sizeof() operator in if-statement

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

It prints False .它打印False Why doesn't sizeof() return a value in the if ?为什么 sizeof() 不在if返回值?

  1. sizeof is not a function, it's an operator. sizeof不是一个函数,它是一个运算符。 The parentheses are not part of the operator's name.括号不是运营商名称的一部分。
  2. It's failing because the value generated has the unsigned type size_t , which causes "the usual arithmetic conversions" in which -1 is converted to unsigned, in which case it's a very large number.它失败是因为生成的值具有无符号类型size_t ,这会导致“通常的算术转换”,其中-1被转换为无符号,在这种情况下它是一个非常大的数字。

Basically you're comparing 4 > 0xffffffffu , or something close to that at least.基本上你是在比较4 > 0xffffffffu ,或者至少接近这个值。 See this question for details. 有关详细信息, 请参阅此问题

Unsigned and signed integer promotion (rather "usual arithmetic conversions", to be more precise).无符号和有符号整数提升(更准确地说,是“通常的算术转换”)。 sizeof yields a value of type size_t , and when compared to an unsigned value (which size_t is), -1 is promoted to that type, and overflows and becomes huge. sizeof产生一个size_t类型的值,当与一个无符号值( size_t是)相比时,-1 被提升为该类型,并溢出并变得巨大。

Unsigned integer overflow has well-defined behavior and is to be taken as modulo 2 ^ width , where width is the number of bits in the particular unsigned integer type.无符号整数溢出具有明确定义的行为,并被视为模2 ^ width ,其中width是特定无符号整数类型中的位数。 So, if you have a 32-bit wide size_t and int , for example, your comparison will be equivalent with因此,例如,如果您有一个 32 位宽的size_tint ,则您的比较将等同于

if (4 > 4294967295u)

which is obviously false.这显然是错误的。

  • The operands of the > operator in the if statement are sizeof(int) and -1 . if 语句中 > 运算符的操作数是sizeof(int)-1
  • sizeof(int) is of type size_t , which is guaranteed to be an unsigned integer. sizeof(int)size_t类型,它保证是一个无符号整数。 In practice, size_t will most likely be at least as big as unsigned int on any system out there.实际上,在任何系统上, size_t很可能至少与unsigned int一样大。
  • -1 is of type int , which is equivalent to signed int . -1int类型,它等价于signed int
  • No integer promotions occur, as both operands are of large enough integer types.没有整数提升发生,因为两个操作数都是足够大的整数类型。
  • Then the two operands are balanced according to a C rule formally called the usual arithmetic conversions .然后根据正式称为通常算术转换的 C 规则平衡两个操作数。

These state (C11 6.3.1.8):这些状态(C11 6.3.1.8):

... ...

Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.否则,如果有符号整数类型操作数的类型可以表示无符号整数类型操作数类型的所有值,则将无符号整数类型操作数转换为有符号整数类型操作数的类型。

Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.否则,两个操作数都被转换为与带符号整数类型的操作数的类型对应的无符号整数类型。

  • The latter of the above will happen, since a (signed) int cannot fit all values of a size_t .上面的后者将会发生,因为(有符号的) int不能适合size_t所有值。
  • Thus -1 is converted to an unsigned integer.因此-1被转换为无符号整数。 In practice, size_t is most likely equivalent to either unsigned int or unsigned long.实际上, size_t很可能相当于 unsigned int 或 unsigned long。 Whatever happens when you store -1 in such a variable is implementation-defined behavior.在这样的变量中存储 -1 时发生的任何事情都是实现定义的行为。
  • On a two's complement computer (99.9% of all computers in the world), -1 will be interpreted as 0xFFFFFFFF (the number of FF depends on the size of an int on the given system).在二进制补码计算机(世界上所有计算机的 99.9%)上,-1 将被解释为0xFFFFFFFF (FF 的数量取决于给定系统上 int 的大小)。
  • 4 > 0xFFFFFFFF evaluates to false. 4 > 0xFFFFFFFF评估为假。

Sizeof is an operator that results in an unsigned long int. Sizeof 是一个运算符,它产生一个 unsigned long int。 Hence, when you compare unsigned long int with -1, which is stored as 0xffffffff (size of int is 4 bytes).因此,当您将 unsigned long int 与 -1 进行比较时,它存储为0xffffffff (int 的大小为 4 个字节)。

-1 is signed integer by default. -1 默认是有符号整数。 But, in comparison between signed int and unsigned int, the compiler goes with implicit typecasting of signed int to unsigned int.但是,在有符号整型和无符号整型之间进行比较时,编译器将有符号整型隐式转换为无符号整型。 This results in unsigned -1 to be approximately equal to 4.6giga value.这导致无符号 -1 大约等于 4.6giga 值。

Hence, the output is false .因此,输出为false

Just test this and see for yourself只需测试一下,自己看看

#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