Является ли бесконечный цикл for (;;);
неопределенным поведением в C? (Это для C++, но я не знаю о C.)
Является ли (пустой) бесконечный цикл неопределенным поведением в C?
Ответы (2)
Нет, поведение оператора for (;;)
хорошо определено в C.
N1570, который практически идентичен официальному В стандарте ISO C 2011 года говорится в разделе 6.8.5, параграф 6:
Оператор итерации, управляющее выражение которого не является константным выражением, который не выполняет операций ввода-вывода, не обращается к изменчивым объектам и не выполняет синхронизации или атомарных операций в своем теле, управляющем выражении или (в случае for) его выражение-3, реализация может считать завершенным.
с двумя сносками:
Пропущенное управляющее выражение заменяется ненулевой константой, которая является константным выражением.
Это предназначено для разрешения трансформаций компилятора, таких как удаление пустых циклов, даже если завершение не может быть доказано.
Первая сноска ясно дает понять, что for (;;)
обрабатывается так, как если бы у него было постоянное управляющее выражение.
Смысл правила в том, чтобы разрешить оптимизацию, когда компилятор не может доказать, что цикл завершается. Но если управляющее выражение является константой, компилятор может тривиально доказать, завершается цикл или нет, поэтому дополнительное разрешение не требуется.
while(1);
не определено в C++? Разве не применимо то же самое рассуждение?
- person user541686; 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");
.
puts("Hello");
, компилируется и выполняется, kill
используется для отправки сигнала программе на выход, и программа изящно делает это, вызывая выход из обработчика сигнала. Где UB, @Deduplicator? Насколько мне известно, единственный UB в сигналах - это возврат программы из одного из сигналов, соответствующих вычислительным ошибкам. Однако здесь этого не происходит, поскольку обработчики сигналов вызывают выход, а не возврат. Пожалуйста, излагайте факты прямо.
- person autistic; 23.03.2015
exit
выполняет обработчики выхода и делает другие вещи, которые вообще не гарантируют работу.
- person Deduplicator; 23.03.2015
puts("Hello");
, потому что в одном из обработчиков atexit может присутствовать неопределенное поведение? Последствие неопределенного поведения в обработчике atexit... не определено. Как это мешает этой оптимизации?
- person autistic; 23.03.2015