Re: Confusion about integer promotions.

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance



"BigMan" <fn42551@xxxxxxxxxxxxxxxx> wrote in message
news:Onyokz$bFHA.1404@xxxxxxxxxxxxxxxxxxxx
"John Carson" <jcarson_n_o_sp_am_@xxxxxxxxxxxxxxx> wrote in message
news:OiWrMp$bFHA.3184@xxxxxxxxxxxxxxxxxxxxxxx
"BigMan" <fn42551@xxxxxxxxxxxxxxxx> wrote in message
news:OHANMG$bFHA.2984@xxxxxxxxxxxxxxxxxxxx
Let's consider this piece of code:

unsigned short  A = 0;
unsigned int    B = 0;
signed int      C = 0;

// For each of these line, should A be promoted to int or to
unsigned int according to the C++ standard if an int can represent
all the values of an unsigned short?

bool            d = A < B;
bool            e = A < C;

Section 4.5/1 of the C++ standard:

"An rvalue of type char, signed char, unsigned char, short int, or
unsigned short int can be converted to an rvalue of type int if int
can represent all the values of the source type; otherwise, the
source rvalue can be converted to an rvalue of type unsigned int."

i.e., promotion is always to the signed version if it is large
enough, otherwise to the unsigned version.

Mixing signed and unsigned integers is very hazardous. I have been
bitten by it more than once and avoid such situations if at all
possible. --
John Carson

First, signed int is large enough on x86 (4 bytes) to hold all values of an unsigned short (2 bytes), so values of the latter type should be promoted to signed int and not to unsigned int. But VC++.NET seem to promote unsigned short either to signed int or to unsigned int regardless of what 4.5/1 says, since it does not issue a singed/unsigned mismatch warning when compiling the above code with the /W4 switch (highest warning level). Is this non-conformant behaviour or what?

Here we need to keep reading to "arithmetic conversions" (I should have provided this information in my original post):

Section 5/9:

"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.
— 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.
[Note: otherwise, the only remaining case is that both operands are int ]"

Thus in your case of

bool            d = A < B;

we first have integral promotions so A gets converted to signed int. Then,
in accordance with the last dashed item, A gets converted to unsigned int.
Thus we end up with two unsigned ints.

In your case of

bool            e = A < C;

we first have integral promotions, as before, so A gets converted to signed
int. A and C are now of the same type, so no further conversion is needed.
You can check that e is false for negative C.

As for signed/unsigned mismatch warnings, I am not aware of any requirement
for these in the standard.

Could you, please, mention some of the problems you have come upon
when mixing signed and unsigned integers?

int x = -1; unsigned int y = 0;

Unless I am careful, I expect

bool b = x < y;

to be true. It is false, since x gets converted to unsigned int and is the
largest possible unsigned int, i.e., 0xFFFFFFFF.


-- John Carson

.



Relevant Pages