它取决于的位宽unsigned/int
。
下面的2个不相同(当unsigned <= 32
位时)。 u32_x + u32_y
变为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.
它们是相同的(当 unsigned >= 34
位)。整数促销造成的 u32_x + u32_y
在64位数学上进行加法运算。顺序无关紧要。
它是UB(unsigned == 33
位)。整数提升导致在加号的33位数学上进行加法运算,并且加号的溢出为UB。
是否允许编译器进行这种重新排序...?
(32位数学运算):重新排序是,但是必须发生相同的结果,因此OP 不会建议重新排序。下面是一样的
// 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);
...我们可以让他们注意到结果不一致并按原样保留表达式顺序吗?
相信是的,但是OP的编码目标尚不清楚。应该u32_x + u32_y
携带捐款吗?如果OP希望做出贡献,则代码应为
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);
但不是
uint64_t u64_z = u32_x + u32_y + u64_a;
uint32_t
值-它们不会溢出,而是溢出。这些不是不同的行为。