C 为什么sizeof运算符在与负数比较时会出现这种情况?

C 为什么sizeof运算符在与负数比较时会出现这种情况?,c,sizeof,implicit-conversion,C,Sizeof,Implicit Conversion,这里到底发生了什么?现在输出为“False”: #包括 int main() { if(sizeof(int)>任意负整数) printf(“真实”); 其他的 printf(“假”); 返回0; } 如果我将其更改为: if (sizeof(int) < any_negative_integer) if(sizeof(int)

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

#包括
int main()
{
if(sizeof(int)>任意负整数)
printf(“真实”);
其他的
printf(“假”);
返回0;
}
如果我将其更改为:

if (sizeof(int) < any_negative_integer)
if(sizeof(int)
输出为“真”

更新:已经询问了,在询问之前我找不到它。

返回未签名的
size\u 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)
                    ^
作为参考,我们从
7.17
通用定义一节中了解到,size\u t是无符号的,该节说明:

 size_t
它是sizeof运算符结果的无符号整数类型;[……]

注意,它没有指定关于该类型的任何其他内容,在我的特定情况下,它恰好是无符号长的,但不必是

-1
的转换是由于第
6.3.1.8节
常用算术转换中所述的常用算术转换,其中说明:

 size_t
[……]

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

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

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

因此,
-1
不会被转换为无符号值的唯一时间是如果int可以表示size\u t的所有值,这里不是这样

为什么
-1
最终是一个大的无符号值,实际上它最终是无符号类型的最大值,这是由于第
6.3.1.3节
中有符号和无符号整数的规定:

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

因此,我们最终得出以下结论:

-1 + (UMAX + 1)
if (sizeof(int) > UMAX )
即:

UMAX
从而得出:

-1 + (UMAX + 1)
if (sizeof(int) > UMAX )

因为
sizeof()
返回一个
size\t
,一个无符号类型。比较有符号和无符号类型会得到令人惊讶的结果,因为在比较之前进行了隐式强制转换。

该死,我甚至没有想到这一点,谢谢,我可以在10分钟后接受它。不过要小心,标准没有说明
int
size\u t
的相对大小。默认情况下,我使用了代码块。所有标志均未选中,现在我已经启用了所有编译器warnings@akki
-pedantic
是一个很好的标志,因为它警告在
gcc
clang
中常见的扩展。是的,当我将
任意负整数
更改为64位整数时,它按预期工作,感谢您的详细说明:)没有“隐式强制转换”这样的事情. 强制转换是一种语法构造,从来都不是隐式的。你是说隐式转换。@PascalCuoq,你叫什么
double d;int i;d=i那么?你不明白“你指的是隐式转换”的哪一部分?