I don\'t get this one!
#include
int main()
{
unsigned short t1 = 0, t2 = 0;
if( t1 < t2-1 )
printf(\" t1 < t2-1\\n\");
The C language performs the "Usual arithmetic conversions" for many operators - the conversions are outlined in 6.3.1.8 of the C99 standard. For integral operands, first promotions are performed, and this is what's causing your issue. The promotions are outlined in 6.3.1.1 (Arithmetic operands/Boolean, characters,and integers), which says among other things:
If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int. These are called the integer promotions. All other types are unchanged by the integer promotions.
The promotions are applied only to objects or expressions with an integer type with a rank less than int
and unsigned int
(or bitfields).
So in your exression:
t1 < t2-1
even though the variables are unsigned short
they are promoted to int, since on your platform int
can represent all the values of unsigned short
. So the expression is evaluated using int
types, and no underflow occurs - the t2-1
part of the expression ends up as negative 1.
In the expression:
s1 < s2-1
the unsigned long
types aren't promoted, because they have a higher 'rank' than int
/unsigned int
, so the expression is evaluated using unsigned arithmetic (with the underflow from the subtraction), and the s2-1
subexpression evaluates to a very large number, not negative 1.
As litb indicated in a comment, if the platform had int
implemented as a 16-bit type (which is permitted - MS-DOS for example), the promotion of unsigned short
would be to unsigned int
instead of int
, since an int
wouldn't be able to represent all values of unsigned short
(unsigned short
must be at least 16-bits). In that case, both if
statements would evaluate to true.