INT02-C. Understand integer conversion rules
Conversions can occur explicitly as the result of a cast or implicitly
as required by an operation. Although conversions are generally
required for the correct execution of a program, they can also lead to
lost or misinterpreted data. Conversion of an operand value to a
compatible type causes no change to the value or the representation.
The C integer conversion rules define how C compilers handle
conversions. These rules include integer promotions, integer
conversion rank, and the usual arithmetic conversions. The intent of
the rules is to ensure that the conversions result in the same
numerical values and that these values minimize surprises in the rest
of the computation. Prestandard C usually preferred to preserve
signedness of the type.
Usual Arithmetic Conversions
The usual arithmetic conversions are rules that provide a mechanism to
yield a common type when both operands of a binary operator are
balanced to a common type or the second and third operands of the
conditional operator ( ? : ) are balanced to a common type.
Conversions involve two operands of different types, and one or both
operands may be converted. Many operators that accept arithmetic
operands perform conversions using the usual arithmetic conversions.
After integer promotions are performed on both operands, the following
rules are applied to the promoted operands:
- If both operands have the same type, no further conversion is needed.
- If both operands are of the same integer type (signed or unsigned), the operand with the type of lesser integer conversion
rank is converted to the type of the operand with greater rank.
- If the operand that has unsigned integer type has rank greater than or equal to the rank of the type of the other operand, the
operand with signed integer type is converted to the type of the
operand with unsigned integer type.
- If the type of the operand with signed integer type can represent all of the values of the type of the operand with unsigned integer
type, the operand with unsigned integer type is converted to the type
of the operand with signed integer type.
- Otherwise, both operands are converted to the unsigned integer type corresponding to the type of the operand with signed integer
type.
https://www.securecoding.cert.org/confluence/display/c/INT02-C.+Understand+integer+conversion+rules
Your code would work if you cast the result to (unsigned short), like this:
printf("n - 2 = %hu\n", (unsigned short)(n - 2));
EDIT: I'll leave this answer here for informative purposes, but you can ignore it. I hadn't seen that DinoCoderSaurus had already answered.