Является ли (пустой) бесконечный цикл неопределенным поведением в C?

Является ли бесконечный цикл for (;;); неопределенным поведением в C? (Это для C++, но я не знаю о C.)


person user541686    schedule 24.03.2013    source источник
comment
См. также: Разрешено ли компиляторам устранять бесконечные циклы?   -  person Shafik Yaghmour    schedule 22.06.2015


Ответы (2)


Нет, поведение оператора for (;;) хорошо определено в C.

N1570, который практически идентичен официальному В стандарте ISO C 2011 года говорится в разделе 6.8.5, параграф 6:

Оператор итерации, управляющее выражение которого не является константным выражением, который не выполняет операций ввода-вывода, не обращается к изменчивым объектам и не выполняет синхронизации или атомарных операций в своем теле, управляющем выражении или (в случае for) его выражение-3, реализация может считать завершенным.

с двумя сносками:

Пропущенное управляющее выражение заменяется ненулевой константой, которая является константным выражением.

Это предназначено для разрешения трансформаций компилятора, таких как удаление пустых циклов, даже если завершение не может быть доказано.

Первая сноска ясно дает понять, что for (;;) обрабатывается так, как если бы у него было постоянное управляющее выражение.

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

person Keith Thompson    schedule 24.03.2013
comment
Суть правила в том, чтобы разрешить оптимизацию, когда компилятор не может доказать, что цикл завершается. Но если управляющее выражение является константой, компилятор может тривиально доказать, завершается цикл или нет. Я хотел бы согласиться, но тогда почему while(1); не определено в C++? Разве не применимо то же самое рассуждение? - person user541686; 24.03.2013
comment
@Mehrdad: ИМХО, так и должно быть, но стандарт C++ не исключает константные управляющие выражения из своей версии правила. - person Keith Thompson; 24.03.2013
comment
Просто чтобы понять, что все это значит: на C вы можете написать программу, в которой логика полностью реализована с помощью обработчиков сигналов, и заставить программу сидеть в бесконечном цикле, ожидая события. Это не похоже на очень умную реализацию чего-то, но я согласен, что язык не должен запрещать это. В С++ это было бы запрещено? - person Jens Gustedt; 24.03.2013

Обоснование этого вопроса, связанного с C++, не имеет отношения к C. В разделе 5.1.2.3p6 указаны пределы оптимизации, и одним из них является:

At program termination, all data written into files shall be identical to the result that execution of the program according to the abstract semantics would have produced.

Теперь возникает вопрос: «Какие данные были бы получены при выполнении в соответствии с абстрактной семантикой?». Предполагая, что сигнал прерывает цикл, программа вполне может завершиться. Однако абстрактная семантика не дала бы никаких результатов до того, как этот сигнал был поднят. Во всяком случае, компилятор может оптимизировать puts("Hello");.

person autistic    schedule 24.03.2013
comment
Для пояснения рассмотрим следующее: программа, в которой нет ничего, кроме пустого цикла, за которым следует puts("Hello");, компилируется и выполняется, kill используется для отправки сигнала программе на выход, и программа изящно делает это, вызывая выход из обработчика сигнала. Где UB, @Deduplicator? Насколько мне известно, единственный UB в сигналах - это возврат программы из одного из сигналов, соответствующих вычислительным ошибкам. Однако здесь этого не происходит, поскольку обработчики сигналов вызывают выход, а не возврат. Пожалуйста, излагайте факты прямо. - person autistic; 23.03.2015
comment
exit выполняет обработчики выхода и делает другие вещи, которые вообще не гарантируют работу. - person Deduplicator; 23.03.2015
comment
@Deduplicator Вы пытаетесь сказать мне, что компилятор может не оптимизировать puts("Hello");, потому что в одном из обработчиков atexit может присутствовать неопределенное поведение? Последствие неопределенного поведения в обработчике atexit... не определено. Как это мешает этой оптимизации? - person autistic; 23.03.2015