13.1 Integral Promotion
When there is more than one operand to an operator, they typically must 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 and is part of Standard C behavior. The MPLAB XC32 C/C++ Compiler performs these integral promotions where required, and there are no options that can control or disable this operation. If you are not aware that the type has changed, the results of some expressions are not what would normally be expected.
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=0, 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. For example:
if((unsigned int)(a - b) < 10)
count++;
The comparison is then done using unsigned int
, in this
case, and the body of the if()
would not be executed.
Another problem that frequently occurs is with the bitwise compliment
operator, ~
. This operator toggles each bit within a value. Consider the
following code:
unsigned char count=0, 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 0xFFFFFFAA and so the
comparison in the above example would fail. The compiler may be 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 MPLAB XC32 C/C++ Compiler will not perform the integral promotion so as to increase the
code efficiency. Consider the following example:
unsigned char a, b, c;
a = b + c;
Strictly speaking, this statement requires that the values of
b
and c
should be promoted to unsigned
int
, the addition performed, the result of the addition cast to the type of
a
, and then the assignment can take place. Even if the result of the
unsigned int
addition of the promoted values of b
and
c
was different to the result of the unsigned char
addition of these values without promotion, after the unsigned int
result
was converted back to unsigned char
, the final result would be the same.
If an 8-bit addition is more efficient than a 32-bit addition, the compiler will 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 ANSI C standard.