Дали (празен) безкраен цикъл е недефинирано поведение в 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: IMHO би трябвало, но стандартът C++ не изключва постоянни контролиращи изрази от своята версия на правилото. - person Keith Thompson; 24.03.2013
comment
Само за да сте сигурни, че улавяте какво означава всичко това: в C можете да напишете програма, в която логиката е напълно внедрена с манипулатори на сигнали и програмата да остане в безкраен цикъл, за да изчака събитие. Това не звучи като много умна реализация на нещо, но съм съгласен, че езикът не трябва да забранява това. В 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 се използва за изпращане на сигнал за излизане от програмата и програмата го прави елегантно, като извиква exit от манипулатора на сигнала. Къде е 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