Почему пустой цикл может исчезнуть при компиляции

Оптимизатор не исполняет программу так, как это делает процессор: он преобразует код, стараясь сохранить его наблюдаемый результат. Если цикл не меняет данные, не обращается к устройствам и не выполняет других заметных действий, его повторение само по себе ничего не добавляет. Компилятор может решить, что до этого места программа вообще не должна бесконечно доходить, и перестроить код так, будто цикл завершается.

В C++ это связано с правилом о продвижении выполнения: реализация в определённых случаях вправе считать, что поток программы рано или поздно совершит наблюдаемое действие или завершится. Если этого не происходит, поведение программы может оказаться неопределённым — стандарт больше не обещает, что она будет бесконечно крутиться именно так, как написано.

Что значит «стереть» на практике

Представим, что после пустого цикла стоит вывод сообщения. Программист может ожидать, что сообщение никогда не появится. Но если компилятор считает цикл участком, который должен завершиться, он способен перенести или выполнить последующий код так, что сообщение появится. В некоторых случаях цикл просто не попадёт в машинный код.

Неопределённое поведение — не команда компилятору удалить цикл, а отсутствие гарантий для этой ситуации. Поэтому результат может отличаться между компиляторами и настройками оптимизации; полагаться на конкретный исход нельзя.

Важное исключение: намеренное ожидание

Это не означает, что C++ запрещает любой бесконечный цикл. Стандарт отдельно защищает простой бесконечный цикл с постоянным условием и без иных наблюдаемых действий: от него не требуется завершаться. А если поток должен ждать изменения, ожидание следует организовать через подходящий механизм — например, атомарную переменную или синхронизацию. Тогда ожидание связано с наблюдаемым взаимодействием, и компилятор не может обращаться с ним как с бесполезным кодом.

Именно поэтому разница между «цикл ничего не делает» и «цикл ждёт события» важна не только для скорости: от неё зависит, обязан ли компилятор сохранить само ожидание.