Выбор ответа Senior Типы и неопределённое поведение спрашивают часто обновлено
Почему проверка x + 1 < x исчезла
Вопрос
Функция bool check(int x) { return x + 1 < x; } после -O2 всегда возвращает false. Почему?
Попробуйте сами
Выберите вариант, и откроется разбор.
Показать ответ и разбор
Коротко
Правильный ответ: Переполнение int это UB, и компилятор считает x + 1 x. Оптимизатор вправе предполагать, что UB в корректной программе не происходит.
Варианты ответа
- Это баг оптимизатора GCC, исправленный в новых версиях
- При
-O2целые считаются в 64 битах, и переполнения нет - Переполнение
intэто UB, и компилятор считаетx + 1 > xправильный ответ - Компилятор вычислил функцию для всех возможных значений
x
Разбор
Оптимизатор вправе предполагать, что UB в корректной программе не происходит. Раз x + 1 не может переполниться, неравенство x + 1 < x ложно для всех допустимых входов, и проверка сворачивается в константу. Правильная проверка: x == INT_MAX или __builtin_add_overflow(x, 1, &r).
- Это не баг: поведение разрешено стандартом.
- Тип
intостаётся 32-битным при любых флагах. - Перебора значений нет, это алгебраическое упрощение.
Ответьте сами, а не прочитайте
В тренажёре вопрос попадёт в повторения и вернётся, когда начнёт забываться. Плюс билеты с зачётом: 20 вопросов, не больше 2 ошибок.
Предыдущий вопрос
Сопоставьте пример и вид поведения
Следующий вопрос
Что выведет: арифметика с char и bool
Ещё по теме «Типы и неопределённое поведение»
- Порядок байтов: перевернуть uint32 и посчитать единицы
- Умножение int64 с проверкой переполнения
- Середина двух int64 без переполнения
- std::bit_cast
- Что C++20 изменил для знаковых целых
- Порядок вычисления аргументов функции
- Объясни, что такое неопределённое поведение
- Продвижение unsigned char