这段代码输出"False"的原因是什么?

4

这段C代码的输出结果是"False",并且执行了else块。

sizeof(int)的值为4,但是sizeof(int) > -1的值为0。

我不明白发生了什么。

#include <stdio.h>
void main()
{
    if (sizeof(int) > -1 )
    {
       printf("True");
    }
    else
    {
        printf("False");
    }
    printf("\n%d", (sizeof(int)) ); //output: 4
    printf("\n%d", (sizeof(int) > -1) ); //output: 0
}

2
启用所有编译器警告。你应该会得到一些警告。 - Andrew Henle
sizeof (int) > -1 converts -1 to unsigned and is the same as sizeof (int) > 4294967295 - pmg
1
如果我没记错的话,发生的情况是-1在二进制补码中表示为11111...1。如果你告诉编译器它是无符号的,那么11111.....1的最后一位将不会是4294967295。 - dreamcrash
void main() 不是错误的。否则我必须写额外的一行 return 0 - Deepak Gautam
1
@DeepakGautam 这是错误的。它只在一些扩展中有效,比如Turbo C或MSVC,或者在一个独立的环境中,否则它是完全被禁止的。阅读其他问题以获取更多信息。而且,*否则我必须写额外的行return 0*也是错误的。在C99中,如果您没有编写返回语句,**会隐式添加一个return 0**。请参见为什么main()不需要返回语句?(重复) - phuclv
显示剩余5条评论
3个回答

6
你的sizeof(int) > -1测试比较了两个无符号整数。这是因为sizeof操作符返回一个size_t值,它是unsigned类型,所以-1值会被转换为它的“等效”表示作为无符号值,其实将成为无符号整数的最大可能值。
为了解决这个问题,你需要显式地sizeof的值强制转换为有符号的int
    if ((int)sizeof(int) > -1) {
        printf("True");
    }

为什么它会将-1转换为等价值?为什么不将"sizeof(int)"转换为int类型? - Deepak Gautam
2
因为规则如此:https://dev59.com/zG035IYBdhLWcg3wcvmS - abelenky
2
@abelenky确实如此(尽管该帖子是针对C ++的)。来自C11草案标准(6.3.1.8):否则,如果具有无符号整数类型的操作数的等级大于或等于另一个操作数的类型的等级,则具有有符号整数类型的操作数将转换为具有无符号整数类型的操作数的类型。 - Adrian Mole
所以这是隐式行为。谢谢@abelenky - Deepak Gautam
2
-1被按值而非表示转换为2^N−1,其中N是“size_t”中的位数。例如,在二进制补码(111…111)、一的补码(111…110)和符号大小表示(100…001)中,“-1”有不同的表示形式,但根据C标准,“(size_t) -1”始终为2^N−1。另外请注意,“size_t”可能比“int”窄,在这种情况下它会被提升,而“-1”则不会,并且“sizeof(int)> -1”会计算为true。 - Eric Postpischil
@EricPostpischil 您是正确的(当然)。然而,我的解决方案将起作用,即使在 size_tint 更窄的非常罕见的情况下(尽管那时它将被认为是多余的)。 - Adrian Mole

3

sizeof运算符返回一个size_t类型的结果。

size_t是一个无符号类型,而-1不是。

-1转换为与size_t相同的类型时,会出现问题(-1变成了一个非常大的数字,比sizeof(int)大得多)。

由于sizeof返回一个无符号值(根据定义不能为负),像您的比较这样的比较没有意义。此外,标准C不允许零大小的对象或类型,因此即使sizof(any_type_or_expression) > 0也总是为真。


2

在表达式中混合使用有符号值和无符号值时要小心(而 sizeof 产生一个无符号的 size_t )。

在相当数量的情况下(包括此处),编译器将在执行操作之前将两个值转换为相同的类型--并且当您混合使用有符号值和无符号值时,通常涉及的相同类型将是无符号类型。因此,在这种情况下发生的情况是 -1 被转换为无符号值,当转换为无符号值时, -1 始终转换为该无符号类型可以容纳的最大值。

从那里开始,其余部分可能相当清楚,我猜测。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接