8.4.1. 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 longs, and a = 0x00000000FFFFFFFF (or 4 294 967 295 in decimal) for 64-bit longs. 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.

Copyright © 2015 ARM. All rights reserved.ARM DEN0024A
Non-ConfidentialID050815