Dodanie dwóch 32-bitowych liczb całkowitych może spowodować przepełnienie liczb całkowitych:
uint64_t u64_z = u32_x + u32_y;
Tego przepełnienia można uniknąć, jeśli jedna z 32-bitowych liczb całkowitych jest najpierw rzutowana lub dodawana do 64-bitowej liczby całkowitej.
uint64_t u64_z = u32_x + u64_a + u32_y;
Jeśli jednak kompilator zdecyduje się zmienić kolejność dodawania:
uint64_t u64_z = u32_x + u32_y + u64_a;
nadal może wystąpić przepełnienie całkowitoliczbowe.
Czy kompilatorom wolno dokonywać takiej zmiany kolejności, czy też możemy im ufać, że zauważą niespójność wyników i zachowają kolejność wyrażeń bez zmian?
((uint32_t)-1 + (uint32_t)1) + (uint64_t)0
skutkuje 0
, podczas gdy (uint32_t)-1 + ((uint32_t)1 + (uint64_t)0)
wyniki są 0x100000000
, a te dwie wartości nie są równe. Dlatego ważne jest, czy kompilator może zastosować tę transformację. Ale tak, standard używa słowa „przepełnienie” tylko dla liczb całkowitych ze znakiem, a nie bez znaku.
uint32_t
wartościami - które nie przepełniają się, zawijają się. To nie są różne zachowania.