> Ну, допустим. Дело же не в нём.Компилер обязан поддерживать заявленную абстракцию. В том числе и в оптимизере, в виде как если бы его не было. Если оптимизированный код отличается в поведении и он не уповал на UB, это уже будет баг оптимизатора тогда. На самом деле конечно больше баг стандартов абы как писаных, но, вот, хоть немного выправлять начинают это безобразие.
> Проблема в том, что оптимизатор может заложиться на тот факт, что число
> не переполняется, а значит и можно выпилить явные/неявные ветки кода,
> ожидающие переполнения
Для unsigned это вообще оптимизация - заложиться в коде на размер чтобы mod 2^N вообще нахаляву получить. Актуально криптоалгоритмам всяким и тому подобному. Для signed это не практиковалось из-за UB.
> Оптимизатор видит, что x == 10 и x только инкрементится — всё,
> ветку if (x == 9) {} можно просто выкинуть
Это катит только если он может _доказать_ это. И даже так он может лопухнуться, потому что видит он все-таки не все. Скажем IRQ - оптимизер не видит, однако его вышибают в пользу другого кода. Для подобных случаев есть volatile. В чем то похожие проблемы есть в многопоточных конструкциях.
> У нас не механизм переполнения оказывает влияние на производительность, а само
> наличие такой гарантии
А вот это большой вопрос. Оптимизер может в дофига случаев пруфнуть те или иные граничные условия и вообще например обрубить функцию с кучей switch ... case до пары команд, доказав что оно получает только 1, 5 и 7 на вход по вообще всей программе. LTO в этом очень крут.
> Так стандарт не позволяет переполнения, а значит и оптимизатор, выкидывающий лишние ветки,
> тоже ничего не нарушает — он заложился на отсутствие гарантий. Из-за
> этого, например, код с беззнаковыми может быть местами медленнее
Это было актуально ДО C23 но актуально ли для него - а вот это интересно.
> Стандарт — нет, но его черновик можно посмотреть или на гитхабе комитета
> в виде исходников, или собранный на eel.is/c++draft
Зачем мне драфт на C++ если мы про си?