if语句中的sizeof()运算符

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

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

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

基本上你比较4 > 0xffffffffu ,或者至less接近。 看到这个问题的细节。

无符号和有符号整数提升(而不是“通常的算术转换”,更精确)。 sizeof产生size_ttypes的值,当与无符号值( size_t是)相比时,-1被提升为该types,并溢出并变得巨大。

无符号整数溢出具有定义良好的行为,取模2 ^ width ,其中width是特定无符号整数types中的位数。 所以,例如,如果你有一个32位宽的size_tint ,那么你的比较就相当于

 if (4 > 4294967295u) 

这显然是错误的。

  • if语句中>运算符的操作数是sizeof(int)-1
  • sizeof(int)的types是size_t ,它保证是一个无符号整数。 实际上,在任何系统上, size_t都可能至less和unsigned int一样大。
  • -1的types是int ,相当于signed int
  • 由于两个操作数都具有足够大的整数types,因此不会发生整数升级。
  • 然后这两个操作数根据C规则进行平衡 ,正式称为通常的算术转换

这些状态(C11 6.3.1.8):

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

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

  • 上面的后一个将会发生,因为(signed) int不能适合size_t所有值。
  • 因此-1被转换为无符号整数。 实际上, size_t最有可能等于unsigned int或unsigned long。 无论在这个variables中存储-1时发生的是实现定义的行为。
  • 在二进制补码计算机上(世界上所有计算机的99.9%),-1将被解释为0xFFFFFFFF (FF的数目取决于给定系统上的int的大小)。
  • 4 > 0xFFFFFFFF计算结果为false。

只要testing一下,看看自己

 #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); } 

Sizeof是一个导致unsigned long int的运算符。 因此,当你比较unsigned long int和-1时,它被存储为0xffffffff (int的大小是4字节)。

-1是缺省值的有符号整数。 但是,在signed int和unsigned int之间进行比较,编译器将带符号int的隐式types转换为unsigned int。 这导致无符号-1大约等于4.6giga值。

因此,输出是false