There is no such as "demotion" of integers in C, but there are promotions. I believe you're confusing promotion and demotion with conversion.
An integer promotion occurs when an integer type smaller than int
is used in an expression, where in most cases it will be promoted to either int
or unsigned int
. This is spelled out in section 6.3.1.1p2 of the C standard:
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. All other types are unchanged by the integer promotions.
This differs from a conversion, which occurs when any type changes to another type, whether the new type is larger or smaller than the original type.
Now applying this to your sample code:
x = 'c';
The assignment operator converts the right operand to the type of the left operand. Character constants have type int
, so the assignment performs a conversion from int
to unsigned char
y = 1;
Decimal integer constants with no suffix have type int
, so no conversion or promotion here.
z = 2;
This assignment performs a conversion from int
to long int
.
aux = x;
This assignment performs a conversion from unsigned char
to int
.
aux = y;
Both sides have the same type, so no conversion.
aux = z;
This assignment performs a conversion from long int
to int
.
aux = x + y; //ZX
Looking at the +
operator first, the left operand x
is first promoted to int
. Both operands now have type int
, so no other conversions, and the result of x + y
has type int
. For the assignment, both sides have the same type so no conversion is applied
aux = y + z;
Looking at the +
operator first, there is no promotion because both operands are at least as large as int
. Because the left operand is an int
and the right operand is a long int
, the left operand is converted to long int
and the result of y + z
has type long int
. This result is then converted to int
for assignment to aux
.