In the C language, with this code snippet:
uint16_t a = 243;
uint16_t b = 65535;
uint16_t max = 65535;
if ((a + b) > max)
{
printf("Out of range!");
}
else
{
printf("Within range.");
}
The result will be "Out of range!". What type conversion rules apply in this case? Can someone point me to a documented source?
Thanks!
From the C Standard (6.5.6 Additive operators)
4 If both operands have arithmetic type, the usual arithmetic conversions are performed on them.
and (6.5.8 Relational operators)
3 If both of the operands have arithmetic type, the usual arithmetic conversions are performed.
and at last (6.3.1.8 Usual arithmetic conversions)
- ... Otherwise, the integer promotions are performed on both operands.
and (6.3.1.1 Boolean, characters, and integers)
2 The following may be used in an expression wherever an int or unsigned int may be used: — An object or expression with an integer type (other than int or unsigned int) whose integer conversion rank is less than or equal to the rank of int and unsigned int. — A bit-field of type _Bool, int, signed int, or unsigned int. If an int can represent all values of the original type (as restricted by the width, for a bit-field), the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. 58) All other types are unchanged by the integer promotions.
So in the condition of the if statement
if ((a + b) > max)
all operands are converted to the type int
according to the integer promotions. And an object of the type int
is able to store the value of the integer expression a + b
where each operand is in turn converted to the type int
.
In fact the above if statement you may imagine the following way
if ( ( ( int )a + ( int )b ) > ( int )max )
or like
if ( ( ( unsigned int )a + ( unsigned int )b ) > ( unsigned int )max )
depending on whether the type int
or unsigned int
can store the values of the type uint16_t
.
An overflow can occur if for example the size of the type int
or unsigned int
is the same as the size of the type uint16_t
.