这究竟是为什么用时一个负数比较sizeof操作符? [英] Why is this happening with the sizeof operator when comparing with a negative number?

查看:150
本文介绍了这究竟是为什么用时一个负数比较sizeof操作符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是真正发生在这里?输出现在是假:

 的#include<&stdio.h中GT;诠释的main()
{
     如果(sizeof的(INT)> any_negative_integer)
         的printf(真);
     其他
         的printf(假);
     返回0;
}

如果我将其更改为:

 如果(sizeof的(INT)LT; any_negative_integer)

输出为真。

更新:href=\"http://stackoverflow.com/questions/17293749/sizeof-operator-in-if-statement\">同样的问题已经问

解决方案

的sizeof 返回为size_t 这是无符号的,因此 1 正在转换为一个非常大的无符号数。使用正确的警戒线将在这里帮助, -Wconversion -Weverything note这是不是在生产中使用 的)标志警告我们:

 警告:隐式转换修改符号性:'诠释'到'无符号长'[-Wsign转换]
   如果(的sizeof(int)的-1个)
                   〜^〜

有关 GCC 您收到使用 -Wextra 标记类似的警告:

 警告:符号和无符号整数前pressions之间的比较[-Wsign  - 比较]
    如果(的sizeof(int)的-1个)
                    ^

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

 为size_t


  

这是sizeof操作符的结果的无符号整型; [...]


请注意,它没有指定在我的具体情况下,任何关于类型,它正好是的无符号长的,但它并没有要。

的转换 1 是由于的正常的算术转换的覆盖部分 6.3.1.8 常见的算术转换的它说:


  

[...]


  
  

否则,如果具有无符号整型操作数的秩大于或
  等于其它操作数的类型的秩,则与操作数
  有符号整数类型转换为无符号的操作数的类型
  整数类型。


  
  

否则,如果与符号整型操作数的类型可以重新present
  所有与无符号整型操作数的类型的值,则
  与无符号整型的操作数转换为的类型
  操作有符号整数类型。


  
  

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


所以,唯一的时间 1 不会被转换为无符号的价值是,如果的 INT 的可以重新present所有的值的为size_t 的,这是不是这里的情况。

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


  

否则,如果新类型是无符号的值是通过反复增加或转换
  减去超过可重新$ P $在新型psented最大值多一个
  直到该值是在新的类型的范围。 49)


因此​​,我们结束了:

  -1 +(UMAX + 1)

这是:

  UMAX

和因此结了:<​​/ P>

 如果(sizeof的(INT)&GT; UMAX)

What's really happening here? The output now is "False":

#include <stdio.h>

int main()
{
     if (sizeof(int) > any_negative_integer)
         printf("True");
     else
         printf("False");
     return 0;
}

If I change it to:

if (sizeof(int) < any_negative_integer)

the output is "True".

Update: the same question has already been asked, I could not find it before asking.

解决方案

sizeof returns size_t which is unsigned and so -1 is being converted to a very large unsigned number. Using the right warning level would have helped here, clang with the -Wconversion or -Weverything(note this is not for production use) flags warns us:

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

For gcc you receive a similar warning using the -Wextra flag:

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

For reference, we know size_t is unsigned from the draft C99 standard section 7.17 Common definitions which says:

 size_t

which is the unsigned integer type of the result of the sizeof operator;[...]

Note, it does not specify anything else about the type, in my specific case it happens to be unsigned long but it does not have to be.

The conversion of -1 is due to the usual arithmetic conversion covered in section 6.3.1.8 Usual arithmetic conversions which says:

[...]

Otherwise, if the operand that has unsigned integer type has rank greater or equal to the rank of the type of the other operand, then the operand with signed integer type is converted to the type of the operand with unsigned integer type.

Otherwise, if the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer type, then the operand with unsigned integer type is converted to the type of the operand with signed integer type.

Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer type.

So the only time -1 would not be converted to an unsigned value would be if int could represent all the values of size_t, which is not the case here.

Why -1 ends up being a large unsigned value, actually it ends up being being the max value of the unsigned type is due to section 6.3.1.3 Signed and unsigned integers which says:

Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.49)

So we end up with:

-1 + (UMAX + 1)

which is:

UMAX

and thus end up with:

if (sizeof(int) > UMAX )

这篇关于这究竟是为什么用时一个负数比较sizeof操作符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆