Suppose you have the following code:
#include <stdio.h>
int main()
{
unsigned x = 1;
char y = -1;
if (x > y)
printf("x > y\n");
else
printf("x <= y\n");
return 0;
}
What does really happen here? Since we are dealing with integer types, first the integer promotions are applied, and then the arithmetic conversions are applied.
If
char
is equivalent to signed char
:char
is promoted toint
(Integer Promotions, ISO C99 §6.3.1.1 ¶2)- Since
int
andunsigned
have the same rank,int
is converted tounsigned
(Arithmetic Conversions, ISO C99 §6.3.1.8)
If
char
is equivalent to unsigned char
:char
may be promoted to eitherint
orunsigned int
:- If
int
can represent allunsigned char
values (typically becausesizeof(int) > sizeof(char)
),char
is converted toint
. - Otherwise (typically because
sizeof(char)==sizeof(int)
),char
is converted tounsigned
.
- If
- Now we have one operand that is either
int
orunsigned
, and another that isunsigned
. The first operand is converted tounsigned
.
The rules that are applied are the following:
Integer promotions: An expression of a type of lower rank that
int
is converted to int
if int
can hold all of the values of the original type, to unsigned
otherwise.Arithmetic conversions: Try to convert to the larger type. When there is conflict between signed and unsigned, if the larger (including the case where the two types have the same rank) type is unsigned, go with unsigned. Otherwise, go with signed only in the case it can represent all the values of both types.
Conversions between integer types(ISO C99 §6.3.1.3):
- Conversion of an out-of-range value to an unsigned integer type is done via wrap-around (modular arithmetic).
- Conversion of an out-of-range value to a signed integer type is implementation defined, and can raise a signal (such as SIGFPE).
Ranks: Every type has a rank. unsigned types have the same rank as the corresponding signed type. Ranks satisfy the following:
char < short < int < long < long long
.Representation of integer types:
- Signed types consist of sign bits, padding bits and value bits.
- Unsigned types consists of padding bits and value bits.
- An unsigned type has to have a number of value bits greater or equal to the number of value bits of its corresponding signed type.
Now we can rephrase part of the above as:
unsigned char
may be promoted to eitherint
orunsigned int
:- If
int
can represent allunsigned char
values (because the number of value bits ofint >=
number of value bits ofunsigned char
),unsigned char
is converted toint
. - Otherwise (because the number of value bits of
int <
number of value bits ofunsigned char
),
unsigned char
is converted tounsigned
.
- If
Borderline example: a system with an
unsigned char
type with 1 padding bit and 31 value bits, and an int
type with 1 sign bit and 31 value bits would fall into the first condition (and be an exception to the previous rule of thumb using sizeof()
).
No comments:
Post a Comment