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:charis promoted toint(Integer Promotions, ISO C99 §6.3.1.1 ¶2)- Since
intandunsignedhave the same rank,intis converted tounsigned(Arithmetic Conversions, ISO C99 §6.3.1.8)
If
char is equivalent to unsigned char:charmay be promoted to eitherintorunsigned int:- If
intcan represent allunsigned charvalues (typically becausesizeof(int) > sizeof(char)),charis converted toint. - Otherwise (typically because
sizeof(char)==sizeof(int)),charis converted tounsigned.
- If
- Now we have one operand that is either
intorunsigned, 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 charmay be promoted to eitherintorunsigned int:- If
intcan represent allunsigned charvalues (because the number of value bits ofint >=number of value bits ofunsigned char),unsigned charis converted toint. - Otherwise (because the number of value bits of
int <number of value bits ofunsigned char),unsigned charis 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