It depends on bit width of unsigned/int
.
The below 2 are not the same (when unsigned <= 32
bits). u32_x + u32_y
becomes 0.
u64_a = 0; u32_x = 1; u32_y = 0xFFFFFFFF;
uint64_t u64_z = u32_x + u64_a + u32_y;
uint64_t u64_z = u32_x + u32_y + u64_a; // u32_x + u32_y carry does not add to sum.
They are the same (when unsigned >= 34
bits). Integer promotions caused u32_x + u32_y
addition to occur at 64-bit math. Order is irrelevant.
It is UB (when unsigned == 33
bits). Integer promotions caused addition to occur at signed 33-bit math and signed overflow is UB.
Are compilers allowed to do such a reordering ...?
(32 bit math): Re-order yes, but same results must occur, so not that re-ordering OP proposes. Below are the same
// Same
u32_x + u64_a + u32_y;
u64_a + u32_x + u32_y;
u32_x + (uint64_t) u32_y + u64_a;
...
// Same as each other below, but not the same as the 3 above.
uint64_t u64_z = u32_x + u32_y + u64_a;
uint64_t u64_z = u64_a + (u32_x + u32_y);
... can we trust them to notice the result inconsistency and keep the expression order as is?
Trust yes, but OP's coding goal is not crystal clear. Should u32_x + u32_y
carry contribute? If OP wants that contribution, code should be
uint64_t u64_z = u64_a + u32_x + u32_y;
uint64_t u64_z = u32_x + u64_a + u32_y;
uint64_t u64_z = u32_x + (u32_y + u64_a);
But not
uint64_t u64_z = u32_x + u32_y + u64_a;