4.5.1 Integral Promotion
Integral promotion changes the type of some expression values. MPLAB XC8 C Compiler always performs integral promotion in accordance with the C standard, but this action can confuse those who are not expecting such behavior.
When there is more than one operand to an operator, the operands must typically be of exactly the same type. The compiler will automatically convert the operands, if necessary, so they do have the same type. The conversion is to a “larger” type so there is no loss of information; however, the change in type can cause different code behavior to what is sometimes expected. These form the standard type conversions.
Prior to these type conversions, some operands are unconditionally converted to a larger type, even if both operands to an operator have the same type. This conversion is called integral promotion. The compiler performs these integral promotions where required and there are no options that can control or disable this operation.
Integral promotion is the implicit conversion of enumerated types,
signed
or unsigned
varieties of
char
, short int
or bit-field types to
either signed int
or unsigned int
. If the result
of the conversion can be represented by an signed int
, then that
is the destination type, otherwise the conversion is to unsigned int.
Consider the following example.
unsigned char count, a=0, b=50;
if(a - b < 10)
count++;
The unsigned char
result of a - b
is 206
(which is not less than 10), but both a
and b
are converted to signed int
via integral promotion before the
subtraction takes place. The result of the subtraction with these data types is
-50 (which is less than 10) and hence the body of the if
statement is executed.
If the result of the subtraction is to be an unsigned quantity, then apply
a cast, as in the following example, which forces the comparison to be done as
unsigned int
types:
if((unsigned int)(a - b) < 10)
count++;
Another problem that frequently occurs is with the bitwise complement
operator, ~
. This operator toggles each bit within a value.
Consider the following code.
unsigned char count, c;
c = 0x55;
if( ~c == 0xAA)
count++;
If c
contains the value 0x55, it often assumed that
~c
will produce 0xAA; however, the result is instead 0xFFAA
for compilers using a 16-bit int
, or 0xFFFFFFAA for compilers
that use a 32-bit int
, and so the comparison in the above example
would fail. The compiler is able to issue a mismatched comparison error to this
effect in some circumstances. Again, a cast could be used to change this
behavior.
The consequence of integral promotion as illustrated above is that
operations are not performed with char
-type operands, but with
int
-type operands. However, there are circumstances when
the result of an operation is identical regardless of whether the operands are of
type char
or int
. In these cases, the compiler
might not perform the integral promotion so as to increase the code efficiency.
Consider this example.
unsigned char a, b, c;
a = b + c;
Strictly speaking, this statement requires that the values of
b
and c
are promoted to unsigned
int
, the addition is performed, the result of the addition is cast
to the type of a
and that result is assigned. In this case, the
value assigned to a
will be the same whether the addition is
performed as an int
or char
, and so the compiler
might encode the former.
If in the above example, the type of a
was
unsigned int
, then integral promotion would have to be
performed to comply with the C Standard.