与负数进行比较时,为什么会出现sizeof运算符?

时间:2014-02-26 16:20:59

标签: c sizeof implicit-conversion

这里到底发生了什么?输出现在为“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)

输出为“True”。

更新:same question已被询问,我在询问之前找不到它。

2 个答案:

答案 0 :(得分:27)

sizeof返回size_t,这是无符号的,因此-1正在转换为非常大的无符号数。使用正确的警告级别会对此有所帮助,clang使用-Wconversion-Weverything note this is not for production use )标记警告我们:

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)
                    ^

作为参考,我们知道来自draft C99 standard部分7.17 公共定义 size_t unsigned ,其中说明:

 size_t
  

这是sizeof运算符的结果的无符号整数类型; [...]

注意,它没有指定关于该类型的任何其他内容,在我的特定情况下,它恰好是 unsigned long ,但它不一定是。

-1的转换是由6.3.1.8 常规算术转换部分中涵盖的通常的算术转换引起的,其中包含:

  

[...]

     

否则,如果具有无符号整数类型的操作数的等级大于或等于   等于另一个操作数的类型的等级,然后是操作数   有符号整数类型转换为带有unsigned的操作数的类型   整数类型。

     

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

     

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

所以唯一的时间-1不会被转换为无符号值,如果 int 可以表示 size_t 的所有值,这不是案例在这里。

为什么-1最终成为一个大的无符号值,实际上它最终成为无符号类型的最大值是由于6.3.1.3 符号和无符号整数其中说:

  

否则,如果新类型是无符号的,则通过重复添加或转换该值   减去一个可以在新类型中表示的最大值   直到该值在新类型的范围内。 49)

所以我们最终得到:

-1 + (UMAX + 1)

是:

UMAX

因此最终得到:

if (sizeof(int) > UMAX )

答案 1 :(得分:2)

由于sizeof()返回size_t,因此为无符号类型。由于在比较之前隐式转换,比较有符号和无符号类型可能会产生令人惊讶的结果。