与负数相比,为什么sizeof运算符会发生这种情况?

这里真的发生了什么? 现在的输出是“False”:

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

如果我将其更改为:

 if (sizeof(int) < any_negative_integer) 

输出是“真”。

更新: 同样的问题已经被问到,我找不到之前问。

sizeof返回size_t ,它是无符号的,所以-1被转换成非常大的无符号数。 使用正确的警告级别在这里会有所帮助,用-Wconversion-Weverything注意这不是用于生产用途 )标志警告我们:

 warning: implicit conversion changes signedness: 'int' to 'unsigned long' [-Wsign-conversion] if (sizeof(int) > -1) ~ ^~ 

对于gcc ,使用-Wextra标志会收到类似的警告:

 warning: comparison between signed and unsigned integer expressions [-Wsign-compare] if (sizeof(int) > -1) ^ 

作为参考,我们知道size_t是从C99标准草案 7.17 草案中 未签名的

  size_t 

这是sizeof运算符结果的无符号整数types; […]

注意,它没有指定types的任何其他内容,在我的具体情况下它恰好是无符号的长整型,但不一定是。

-1的转换是由于6.3.1.8 常见的算术转换引起的。

[…]

否则,如果具有无符号整数types的操作数的级别大于或等于另一操作数的types的级别,则将具有有符号整数types的操作数转换为具有无符号整数types的操作数的types。

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

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

所以唯一的时间-1不会被转换成一个无符号的值将是如果int可以代表size_t的所有值,这不是这里的情况。

为什么-1最后是一个很大的无符号值,实际上它是无符号types的最大值,这是由于6.3.1.3节的有符号和无符号整数 ,它们表示:

否则,如果新types是无符号的,则通过重复地增加或减去新types中能够表示的最大值之一来转换该值,直到该值在新types的范围内。 49)

所以我们结束了:

 -1 + (UMAX + 1) 

这是:

 UMAX 

并因此最终:

 if (sizeof(int) > UMAX ) 

因为sizeof()返回一个size_t ,一个无符号types。 比较有符号types和无符号types会导致令人惊讶的结果,因为在比较之前进行隐式转换。

Interesting Posts