Why is this happening with the sizeof operator when comparing with a negative number? [duplicate]

匿名 (未验证) 提交于 2019-12-03 01:18:02

问题:

This question already has an answer here:

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

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

If I change it to:

if (sizeof(int) 

the output is "True".

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

回答1:

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 ) 


回答2:

Because sizeof() returns a size_t, an unsigned type. Comparing signed and unsigned types can give surprising results due to implicit casting before the comparison.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!