有符号/无符号比较 [英] Signed/unsigned comparisons
问题描述
我想了解为什么以下代码不会在指定的地方发出警告。
// 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屋!