Баг воспроизводится только в 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`, а сдвиг знакового числа переполнение вообще не отслеживает
