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.