Adding two 32-bit integers can result an integer overflow:
uint64_t u64_z = u32_x + u32_y;
This overflow can be avoided if one of the 32-bit integers is first casted or added to a 64-bit integer.
uint64_t u64_z = u32_x + u64_a + u32_y;
However, if the compiler decides to reorder the addition:
uint64_t u64_z = u32_x + u32_y + u64_a;
the integer overflow might still happen.
Are compilers allowed to do such a reordering or can we trust them to notice the result inconsistency and keep the expression order as is?
If the optimiser does such a reordering it is still bound to the C specification, so such a reordering would become:
uint64_t u64_z = (uint64_t)u32_x + (uint64_t)u32_y + u64_a;
Rationale:
We start with
uint64_t u64_z = u32_x + u64_a + u32_y;
Addition is performed left-to-right.
The integer promotion rules state that in the first addition in the original expression, u32_x
be promoted to uint64_t
. In the second addition, u32_y
will also be promoted to uint64_t
.
So, in order to be compliant with the C specification, any optimiser must promote u32_x
and u32_y
to 64 bit unsigned values. This is equivalent to adding a cast. (The actual optimising is not done at the C level, but I use C notation because that is a notation that we understand.)