| |||

Home > Porting to A64 > Recommendations for new C code > Explicit and implicit type conversions |

The internal promotion and type conversion in C/C++ can cause some unexpected problems when data types of different length and/or sign are mixed in expressions. In particular, it is sometimes important to understand at what point conversions are made in the evaluation of an expression.

For example:

int + long => long;

unsigned int + signed int => unsigned int

int64_t + uint32_t => int64_t

If the loss of sign conversion is carried out before the promotion
to `long`

then the result might be incorrect when
assigned to a signed long.

In cases where unsigned and signed 32-bit integers are mixed in an expression and the result assigned to a signed 64-bit integer, cast one of the operands to its 64-bit type. This causes the other operands to be promoted to 64 bits and no further conversion is required when the expression is assigned. Another solution is to cast the entire expression so that sign extension occurs on assignment. However, there is no one-size-fits-all solution for these problems. In practice, the best way to fix them is to understand what the code is trying to do.

Consider this example, in which you would expect the result
-1 for `a`

:

long a;

int b;

unsigned int c;

b = -2;

c = 1;

a = b + c;

This gives a result of a = -1 (represented as `0xFFFFFFFF`

)
for 32-bit `long`

s, and a = `0x00000000FFFFFFFF`

(or
4 294 967 295 in decimal) for 64-bit `long`

s. Clearly
an unexpected and very wrong result! This is because `b`

is
converted to `unsigned int`

before the addition
(to match `c`

), so the result of the addition is
an `unsigned int`

.

One possible solution is to cast to the longer type before the addition.

long a;

int b;

unsigned int c;

b = -2;

c = 1;

a = (long)b + c;

This gives a result of -1 (or `0xFFFFFFFFFFFFFFFF`

)
in two’s complement representation, and is the expected result.
The calculation is carried out in 64-bit arithmetic and the conversion
to signed now gives the correct result.