Добавление двух 32-битных целых чисел может привести к целочисленному переполнению:
uint64_t u64_z = u32_x + u32_y;
Этого переполнения можно избежать, если сначала преобразовать одно из 32-битных целых чисел или добавить к 64-битному целому числу.
uint64_t u64_z = u32_x + u64_a + u32_y;
Однако, если компилятор решит изменить порядок добавления:
uint64_t u64_z = u32_x + u32_y + u64_a;
целочисленное переполнение все еще может произойти.
Разрешено ли компиляторам выполнять такое переупорядочение или мы можем доверять им, чтобы они заметили несогласованность результатов и сохранили порядок выражений как есть?
((uint32_t)-1 + (uint32_t)1) + (uint64_t)0
приводит к результату 0
, тогда как (uint32_t)-1 + ((uint32_t)1 + (uint64_t)0)
результаты возникают 0x100000000
, и эти два значения не равны. Поэтому важно, может ли компилятор применить это преобразование. Но да, стандарт использует слово «переполнение» только для целых чисел со знаком, а не для беззнаковых.
uint32_t
значениями - которые не переполняются, а переносятся. Это не разные модели поведения.