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

kin*_*oki 10 c sizeof implicit-conversion

这里到底发生了什么?输出现在为"False":

#include <stdio.h>

int main()
{
     if (sizeof(int) > any_negative_integer)
         printf("True");
     else
         printf("False");
     return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果我将其更改为:

if (sizeof(int) < any_negative_integer)
Run Code Online (Sandbox Code Playgroud)

输出为"True".

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

Sha*_*our 27

sizeof返回的size_t是无符号的,因此-1被转换为非常大的无符号数.使用正确的警告级别会对此有所帮助,clang使用-Wconversion-Weverything(注意这不是生产用途)标志警告我们:

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

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

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

作为参考,我们知道的size_t无符号来自C99标准草案部分7.17 的通用定义它说:

 size_t
Run Code Online (Sandbox Code Playgroud)

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

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

的转化-1是由于正常的算术转换覆盖部6.3.1.8 通常的算术转换这表示:

[...]

否则,如果具有无符号整数类型的操作数的秩大于或等于另一个操作数的类型的秩,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型.

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

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

因此,唯一的时间-1不会被转换为无符号值,如果int可以表示size_t的所有值,这不是这里的情况.

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

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

所以我们最终得到:

-1 + (UMAX + 1)
Run Code Online (Sandbox Code Playgroud)

这是:

UMAX
Run Code Online (Sandbox Code Playgroud)

因此最终得到:

if (sizeof(int) > UMAX )
Run Code Online (Sandbox Code Playgroud)