Дали безкраен цикъл като 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
се използва за изпращане на сигнал за излизане от програмата и програмата го прави елегантно, като извиква exit от манипулатора на сигнала. Къде е UB, @Deduplicator? Доколкото ми е известно, единственият UB в сигналите е, ако програмата се върне от един от сигналите, съответстващ на изчислителни грешки. Това обаче не се случва тук, тъй като манипулаторите на сигнали извикват изход, вместо връщане. Моля, изяснете си фактите.
- person autistic; 23.03.2015
exit
изпълнява манипулатори за изход и прави други неща, за които не е гарантирано, че изобщо работят.
- person Deduplicator; 23.03.2015
puts("Hello");
, тъй като недефинирано поведение може да присъства в един от манипулаторите на atexit? Последствието от недефинирано поведение в манипулатор atexit е... недефинирано. Как това спира тази оптимизация?
- person autistic; 23.03.2015