有符号/无符号比较 [英] Signed/unsigned comparisons

查看:186
本文介绍了有符号/无符号比较的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了解为什么以下代码不会在指定的地方发出警告。

  // from limits.h 
#define UINT_MAX 0xffffffff / * maximum unsigned int value * /
#define INT_MAX 2147483647 / * maximum(signed)int value * /
/ * = 0x7fffffff * /

int a = INT_MAX;
// _ int64 a = INT_MAX; //使所有警告消失
unsigned int b = UINT_MAX;
bool c = false;

if(a< b)// warning C4018:'<':signed / unsigned mismatch
c = true;
if(a> b)// warning C4018:'<':signed / unsigned mismatch
c = true;
if(a< = b)// warning C4018:'<':signed / unsigned mismatch
c = true;
if(a> = b)// warning C4018:'<':signed / unsigned mismatch
c = true;
if(a == b)//无警告< --- warning expected here
c = true;
if((unsigned int)a)== b)//无警告(如预期)
c = true;
if(a ==((int)b))//无警告(如预期)
c = true;

我认为这是与背景宣传有关,但最后两个似乎以其他方式说。对我来说,第一个 == 的比较和其他的一样,是一个有符号/无符号的匹配吗?




解决方案

当将signed与unsigned进行比较时,编译器将带符号的值转换为unsigned。对于相等,这没有关系, -1 ==(unsigned)-1 。对于其他比较,以下是真的: -1> 2U



编辑:参考文献:



5/9:


许多二进制运算符需要
算术或枚举操作数
类型导致转换和产生
result类型以类似的方式。
的目的是产生一个公共类型,
也是结果的类型。
这种模式称为通常的
算术转换,其中
定义如下:




  • 如果
    操作数的类型为long double,则
    other将被转换为long
    double。


  • 否则,如果操作数
    是双精度,另一个是
    转换为双精度。


  • 否则,如果
    的操作数是浮点数,则另一个
    应转换为float。

  • 否则,积分促销
    (4.5)将在
    操作数上执行.54)


  • 然后,如果任一操作数
    是无符号长整型,则另一个将
    转换为unsigned long。


  • 否则,如果一个操作数是长整型
    int和其他unsigned int,那么
    如果long int可以表示所有
    值的unsigned int,
    unsigned int将被转换为
    long int;否则,如果任一操作数是
    long,那么操作数
    将转换为unsigned long
    int。


  • <其他应转换为
    long。


  • 否则,如果操作数
    无符号,另一个将
    转换为无符号。



4.7 / 2 :(整数转换)


如果目标类型是unsigned,
,结果值是最小的
无符号整数等于
源整数(模2 n 其中n是
用于表示无符号类型的
的位数。 [注意:在两个
补码表示中,这个
转换是概念性的,并且有
的位模式没有改变(如果
没有截断)。 ]


EDIT2:MSVC警告级别



MSVC的不同警告级别当然是开发者做出的选择。正如我看到的,他们在签名/无符号平等与更大/更小比较方面的选择是有意义的,这是完全主观的:



-1 == -1 表示与 -1 ==(unsigned)-1 相同 - 我发现一个直观的结果。 >

-1< 2 的含义与 -1 < (unsigned)2 - 这不太直观,一瞥,IMO应该得到一个更早的警告。


I'm trying to understand why the following code doesn't issue a warning at the indicated place.

//from limits.h
#define UINT_MAX 0xffffffff /* maximum unsigned int value */
#define INT_MAX  2147483647 /* maximum (signed) int value */
            /* = 0x7fffffff */

int a = INT_MAX;
//_int64 a = INT_MAX; // makes all warnings go away
unsigned int b = UINT_MAX;
bool c = false;

if(a < b) // warning C4018: '<' : signed/unsigned mismatch
    c = true;
if(a > b) // warning C4018: '<' : signed/unsigned mismatch
    c = true;
if(a <= b) // warning C4018: '<' : signed/unsigned mismatch
    c = true;
if(a >= b) // warning C4018: '<' : signed/unsigned mismatch
    c = true;
if(a == b) // no warning <--- warning expected here
    c = true;
if(((unsigned int)a) == b) // no warning (as expected)
    c = true;
if(a == ((int)b)) // no warning (as expected)
    c = true;

I thought it was to do with background promotion, but the last two seem to say otherwise.

To my mind, the first == comparison is just as much a signed/unsigned mismatch as the others?

解决方案

When comparing signed with unsigned, the compiler converts the signed value to unsigned. For equality, this doesn't matter, -1 == (unsigned) -1. For other comparisons it matters, e.g. the following is true: -1 > 2U.

EDIT: References:

5/9: (Expressions)

Many binary operators that expect operands of arithmetic or enumeration type cause conversions and yield result types in a similar way. The purpose is to yield a common type, which is also the type of the result. This pattern is called the usual arithmetic conversions, which are defined as follows:

  • If either operand is of type long double, the other shall be converted to long double.

  • Otherwise, if either operand is double, the other shall be converted to double.

  • Otherwise, if either operand is float, the other shall be converted to float.

  • Otherwise, the integral promotions (4.5) shall be performed on both operands.54)

  • Then, if either operand is unsigned long the other shall be converted to unsigned long.

  • Otherwise, if one operand is a long int and the other unsigned int, then if a long int can represent all the values of an unsigned int, the unsigned int shall be converted to a long int; otherwise both operands shall be converted to unsigned long int.

  • Otherwise, if either operand is long, the other shall be converted to long.

  • Otherwise, if either operand is unsigned, the other shall be converted to unsigned.

4.7/2: (Integral conversions)

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2n where n is the number of bits used to represent the unsigned type). [Note: In a two’s complement representation, this conversion is conceptual and there is no change in the bit pattern (if there is no truncation). ]

EDIT2: MSVC warning levels

What is warned about on the different warning levels of MSVC is, of course, choices made by the developers. As I see it, their choices in relation to signed/unsigned equality vs greater/less comparisons make sense, this is entirely subjective of course:

-1 == -1 means the same as -1 == (unsigned) -1 - I find that an intuitive result.

-1 < 2 does not mean the same as -1 < (unsigned) 2 - This is less intuitive at first glance, and IMO deserves an "earlier" warning.

这篇关于有符号/无符号比较的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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