if语句中的sizeof()运算符
#include <stdio.h> main() { if (sizeof(int) > -1) printf("True"); else printf("False"); }
它打印False
。 为什么sizeof()在if
返回一个值?
-
sizeof
不是一个函数,它是一个运算符。 括号不是运营商名称的一部分。 - 这是失败的,因为生成的值具有无符号types
size_t
,这导致“通常的算术转换”,其中-1
被转换为无符号的,在这种情况下,它是一个非常大的数字。
基本上你比较4 > 0xffffffffu
,或者至less接近。 看到这个问题的细节。
无符号和有符号整数提升(而不是“通常的算术转换”,更精确)。 sizeof
产生size_t
types的值,当与无符号值( size_t
是)相比时,-1被提升为该types,并溢出并变得巨大。
无符号整数溢出具有定义良好的行为,取模2 ^ width
,其中width
是特定无符号整数types中的位数。 所以,例如,如果你有一个32位宽的size_t
和int
,那么你的比较就相当于
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
。