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
- Re: Usual arithmetic conversions + integral promotion for short?
... > converted to an rvalue of type int if int can represent all the values ... conversions", and which for this case states that the integral promotions ... (comp.lang.cpp) - Re: integral promotion, arithmetic conversion, value preserving, unsigned preserving???
... None mentioned anything about integral promotion, ... If an unsigned short has the same bit-size as int, ... conversions. ... Otherwise, if either operand is double, the other is converted to ... (comp.lang.c) - [PATCH v3 04/14] async_xor: permit callers to pass in a dma/page scribble region
... async_xorneeds space to perform dma and page address conversions. ... most cases the code can simply reuse the struct page * array because the ... int src_off = 0; ... (Linux-Kernel) - Re: CAN WE TYPE CAST AN INTEGER AS (VOID *)X..(Like can I return a value (void *)x)
... there is no guarantee that an int might fit into a pointer. ... It is not guaranteed that the two conversions are inverses; that is, it is not guaranteed that the number that emerges from the second conversion is the same value that entered the first. ... on many implementations (I suspect it might fail on AS/400, ... (comp.lang.c) - [PATCH v2 04/11] async_xor: permit callers to pass in a dma/page scribble region
... async_xorneeds space to perform dma and page address conversions. ... most cases the code can simply reuse the struct page * array because the ... int src_off = 0; ... (Linux-Kernel) |
|