Выбор ответа Senior Типы и неопределённое поведение спрашивают часто обновлено

Почему проверка x + 1 < x исчезла

Вопрос

Функция bool check(int x) { return x + 1 < x; } после -O2 всегда возвращает false. Почему?

Попробуйте сами

Выберите вариант, и откроется разбор.

Показать ответ и разбор

Коротко

Правильный ответ: Переполнение int это UB, и компилятор считает x + 1 x. Оптимизатор вправе предполагать, что UB в корректной программе не происходит.

Варианты ответа

  1. Это баг оптимизатора GCC, исправленный в новых версиях
  2. При -O2 целые считаются в 64 битах, и переполнения нет
  3. Переполнение int это UB, и компилятор считает x + 1 > xправильный ответ
  4. Компилятор вычислил функцию для всех возможных значений x

Разбор

Оптимизатор вправе предполагать, что UB в корректной программе не происходит. Раз x + 1 не может переполниться, неравенство x + 1 < x ложно для всех допустимых входов, и проверка сворачивается в константу. Правильная проверка: x == INT_MAX или __builtin_add_overflow(x, 1, &r).

  • Это не баг: поведение разрешено стандартом.
  • Тип int остаётся 32-битным при любых флагах.
  • Перебора значений нет, это алгебраическое упрощение.

Ответьте сами, а не прочитайте

В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.