# comparing signed and unsigned integers

J

#### Joe Van Dyk

What bad things could happen if I compare signed and unsigned integers?
(is that even valid C?)

Thanks,
Joe

Ad

E

#### Eric Sosman

Joe said:
What bad things could happen if I compare signed and unsigned integers?
(is that even valid C?)

Second question first: Yes, it is valid. The operands are
subject to the "usual arithmetic conversions" (6.3.1.8), which
reconcile them to a common type. The comparison is then carried
out in that common type.

First question second: The usual arithmetic conversions may
result in a type that is surprising to the novice, changing the
"obvious" meaning of the expression:

int i = -1;
unsigned int u = i + 1;
if (u > i) ...

Clearly, u is initialized to a value greater than that of i:
after all, i is negative and u is zero, so u must be greater
than i, right? Not so, Grasshopper: after the "usual arithmetic
conversions" (which in this case convert both operands to
unsigned int), the converted i will be UINT_MAX, much *larger*
than u. If you don't understand what's happening, the result
might be a "bad thing."

J

#### Joe Wright

Joe said:
What bad things could happen if I compare signed and unsigned integers?
(is that even valid C?)

Thanks,
Joe

Besides nasal demons?

First, why would you mix signed and unsigned int values for comparison?

These are two different animals and generally shouldn't be compared.

But if you must, check the int for < 0. If negative, there's your answer
because unsigned is >= 0 by definition.

Now, if the int is positive, cast it to unsigned and do the comparison.

Ad

T

#### Tom St Denis

Joe said:
Besides nasal demons?

First, why would you mix signed and unsigned int values for comparison?

These are two different animals and generally shouldn't be compared.

But if you must, check the int for < 0. If negative, there's your answer
because unsigned is >= 0 by definition.

Now, if the int is positive, cast it to unsigned and do the comparison.

My usual solution is to actually review the code. If I know the value
never has to be tested for >= 0 [e.g. decrementing loop] or negative I
convert it to unsigned locally.

Otherwise, I look at the values and use good common sense... e.,g.

int x;
unsigned char myarray[100];
for (x = 0; x < sizeof(myarray); x++) { myarray[x] = 0; }

That will generate the diagnostic with GCC. The fix I use (if I can't
move x to unsigned) is to just realize that myarray is less than the
minimum size for an int and cast the sizeof. e.g.

for (x = 0; x < (int)sizeof(myarray); x++) { ... }

I don't do the cast to "fix" the code, it's just my way of
acknowledging the diagnostic and signalling to myself that I've
addressed the issue.

Tom