Вступить в клуб →
сложнаявопросСборка, тесты и профилирование

Баг воспроизводится только в Release

Функция ищет ближайшую сверху степень двойки и «страхуется» от переполнения проверкой cap > 0:

int round_up_pow2(int need) {
    int cap = 1;
    while (cap > 0 && cap < need) {
        cap *= 2;
    }
    return cap;                    // значение <= 0 означает «не помещается в int»
}

При need = 2000000000 Debug-сборка возвращает отрицательное число, а Release с -O2 зависает в этом цикле навсегда. Как объяснить разницу?

  • Разница в разрядности: в Release значение целиком живёт в 64-битном регистре, переполнения не происходит, и цикл упирается в другое условие
  • Переполнение знакового `int` — неопределённое поведение, поэтому оптимизатор считает `cap > 0` всегда истинным и выкидывает проверку
  • В Release включается развёртка цикла, из-за чего условие `cap < need` проверяется реже одного раза за итерацию и момент выхода проскакивается
  • Виновата оптимизация умножения: `cap *= 2` заменяется сдвигом `cap << 1`, а сдвиг знакового числа переполнение вообще не отслеживает

🔒 Проверка ответа — для участников клуба

  • Проверка ответа
  • Подсказка, если застряли
  • Разбор с объяснением, почему так
  • Прогресс по всем задачам и виртуальные собеседования
Зарегистрироваться →

Регистрация занимает минуту

Другие задачи раздела