views:

308

answers:

3

When a compiler finds a signed / unsigned mismatch, what action does it take? Is the signed number cast to an unsigned or vice versa? and why?

A: 

It could be compiler-specific. If you look at the Question "Should I disable the C compiler signed/unsigned mismatch warning?" you see that in case of "litb" the variable the signed-var got "promoted" to an unsigned value.

In any case there is no "correct" way for a compiler to handle this situation once one variable reaches a certain value (that is, where the most significant bit is set). So, if you have such a warning, be sure to get rid of it ;)

lx
+3  A: 

If operand are integral and there is an unsigned value, then conversion to unsigned is done. For example:

-1 > (unsigned int)1 // as -1 will be converted to 2^nbits-1

Conversion int->unsigned int is: n>=0 -> n; n<0 -> n (mod 2^nbits), for example -1 goes to 2^nbits-1

Conversion unsigned int->int is: n <= INT_MAX -> n; n > INT_MAX -> implementation defined

If the destination type is unsigned, the resulting value is the least unsigned integer congruent to the source integer (modulo 2^n where n is the number of bits used to represent the unsigned type).

If the destination type is signed, the value is unchanged if it can be represented in the destination type (and bit-field width); otherwise, the value is implementation-defined.

Konstantin
As for, "and why?": the standard covers "usual arithmetic conversions" in 5:9. If the only difference between the types of the operands in that one is unsigned, then with a bit of head-scratching, the 4th, 5th and 8th rules in the list together imply what you say.
Steve Jessop
+1  A: 

I don't think C++ deviates from the way C handles signed/unsigned conversions:

Conversion rules are more complicated when unsigned operands are involved. The problem is that comparisons between signed and unsigned values are machine-dependent, because they depend on the sizes of the various integer types. (K&R)

One important factor to consider is whether one of the types is a long integer or not, because that will affect integer promotions. For example, if a long int is compared to an unsigned int, and a long int can represent all the values of an unsigned int, then the unsigned int will be converted to a long int. (Otherwise, they're both just converted to an unsigned long int.)

In most cases, though, the compiler should convert signed integers to unsigned integers if it finds a mismatch.

htw