C 为什么sizeof运算符在与负数比较时会出现这种情况?
这里到底发生了什么?现在输出为“False”: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)
#包括
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代码>那么?你不明白“你指的是隐式转换”的哪一部分?