It is possible that a signed type can represent all numbers represented by the corresponding unsigned type. For example, if an unsigned int is represented using 31 bits of values and 1 padding bits, and a signed int is represented using 31 bits of values and without padding bits. Is implementation allowed?
The standard is set in 6.3.1.8 Usual arithmetic conversions :
Otherwise, whole promotions run on both operands. Then, for advanced operands, the following rules apply: If both operands are of the same type, then no further conversion is required.
Otherwise, if both operands are of integer types or both have unsigned integer types, the operand with the type of a lower integer conversion rank is converted to the operand type with a higher rank.
Otherwise, if the operand with an unsigned integer type has a rank greater than or equal to the ranks of the type of another operand, then the operand with an integer type with a sign is converted to the type of the unsigned operand of an integer type.
Since int and unsigned int have the same rank ( 6.3.1.1 Boolean, characters, and integers ), int converted to unsigned int , but not vice versa:
- The rank of any unsigned integers must be equal to the wound of the corresponding digit integer type, if any.
Integer constants with the suffix u always unsigned (see table in 6.4.4.1 Integer constants ).
6.3.1.1 Boolean, characters, and integers clause 2 also tells us:
The following expressions can be used in an expression: int or unsigned int can:
- an object or expression with an integer type whose integer conversion rank is less than the rank of int and unsigned int.
- a bit field of the type _Bool, int, signed int or unsigned int.
If int can represent all values of the original type, the value is converted to int; otherwise, it will be converted to unsigned int. They are called Share integers. All other types are not affected by whole promotions.
So no, an implementation cannot legally convert an unsigned int to int unless you explicitly ask for it by cast or assignment.
EDIT : Section 2 of 6.3.1.1 Boolean, characters, and integers reads:
- an object or expression with an integer type whose integer conversion rank is less than the rank of int and unsigned int.
(INTERNATIONAL STANDARD ISO / IEC 9899, second edition, 1999-12-01)
- an object or expression with an integer type whose integer conversion rank is less than or equal to the rank of int and unsigned int.
(Project Draft WG14 / N1256 - Septermber 7, 2007 ISO / IEC 9899: TC3)
- an object or expression with an integer type ( except int or unsigned int ) whose integer conversion rank is less than or equal to the rank of int and unsigned internal.
(Committee Draft N1548 - December 2, 2010. ISO / IEC 9899: 201x,
Project N1570 - April 12, 2011 ISO / IEC 9899: 201x)
And just for fun, C ++ 11 4.5 Integral promotions [conv.prom] :
A value of an integer type other than bool, char16_t, char32_t or wchar_t, an integer conversion rank (4.13) less than the rank of int can be converted to prvalue of type int if int can represent all values of the source type; otherwise, the original prvalue value can be converted to a prvalue of type unsigned int.
(N3242 = 11-0012,
N3337 Date: 2012-01-16,
International Standard ISO / IEC 14882 Third Edition 2011-09-01)