The usual arithmetic conversions are performed on the operands of addition. For integer types, this consists of the integer promotions if needed, and if the two operands do not have the same type a further conversion is done to bring them to a common type.
In the first case there are no promotions but the int
operand is converted to unsigned int
because int
can not hold all the possible values of unsigned int
.
In the second case both operands are promoted to int
and stay as an int
since they have a common type.
For reference the draft C11 standard in section 6.5.6
Additive operators says:
If both operands have arithmetic type, the usual arithmetic conversions are performed on
them.
section 6.3.1.8
Usual arithmetic conversions says:
Many operators that expect operands of arithmetic type cause
conversions and yield result types in a similar way. The purpose is to
determine a common real type for the operands and result. For the
specified operands, each operand is converted, without change of type
domain, to a type whose corresponding real type is the common real
type. Unless explicitly stated otherwise, the common real type is also
the corresponding real type of the result, whose type domain is the
type domain of the operands if they are the same, and complex
otherwise. This pattern is called the usual arithmetic conversions
[...]
Otherwise, the integer promotions are performed on both operands. Then the
following rules are applied to the promoted operands
[...]
- Otherwise, if the operand that has unsigned integer type has rank greater or
equal to the rank of the type of the other operand, then the operand with
signed integer type is converted to the type of the operand with unsigned
integer type
[...]
A good reference for the rationale for this can be found in the question: Why must a short be converted to an int before arithmetic operations in C and C++?.