Ошибочно думать о том, что делает «компилятор», рассуждая о неопределенном поведении. Компилятор прозрачный. Поведение находится в вашем коде, а не в компиляторе. Вы должны спросить "что означает мой код INT_MAX - b + c
означает ? Может ли он переполниться? Ответ никогда не в" компиляторе ", а в стандарте.
Стандарт требует только, чтобы отдельные операции, которые появляются в вашей программе , не переполнялись. Он никогда не говорит ничего о каких-либо переписанных выражениях, которые явно не появляются в вашей программе. INT_MAX - b + c
в вашей программе и эквивалентно (INT_MAX - b) + c
. Таким образом, требуется, чтобы (INT_MAX - b)
не переполнялся, а затем результат, добавленный к c
, не переполнялся. INT_MAX + c - b
не отображается в вашей программе, поэтому вам не следует об этом беспокоиться.
Если компилятор переписывает ваше выражение каким-либо образом, он должен убедиться, что переписанное выражение имеет то же видимое поведение, что и у вас, согласно правилу как если бы . Поэтому, если он заменяет INT_MAX - b + c
на INT_MAX + c - b
, он должен убедиться, что переполнение либо не происходит, либо решается прозрачно (например, игнорируется аппаратными средствами).