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 to`int`

(Integer Promotions, ISO C99 §6.3.1.1 ¶2)- Since
`int`

and`unsigned`

have the same rank,`int`

is converted to`unsigned`

(Arithmetic Conversions, ISO C99 §6.3.1.8)

If

`char`

is equivalent to `unsigned char`

:`char`

may be promoted to either`int`

or`unsigned int`

:- If
`int`

can represent all`unsigned char`

values (typically because`sizeof(int) > sizeof(char)`

),`char`

is converted to`int`

. - Otherwise (typically because
`sizeof(char)==sizeof(int)`

),`char`

is converted to`unsigned`

.

- If
- Now we have one operand that is either
`int`

or`unsigned`

, and another that is`unsigned`

. The first operand is converted to`unsigned`

.

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 either`int`

or`unsigned int`

:- If
`int`

can represent all`unsigned char`

values (because the number of value bits of`int >=`

number of value bits of`unsigned char`

),`unsigned char`

is converted to`int`

. - Otherwise (because the number of value bits of
`int <`

number of value bits of`unsigned char`

`),`

`unsigned char`

is converted to`unsigned`

.

- 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