Действительно допустимо вызывать main()
из самого себя, даже избегая переполнения стека тем же методом, который используется для любого другого рекурсивного кода, условие завершения, такое как:
#include <stdio.h>
int main (int argc, char *argv[]) {
printf ("Running main with argc = %d, last = '%s'\n",
argc, argv[argc-1]);
if (argc > 1)
return main(argc - 1, argv);
return 0;
}
который при запуске как testprog 1 2 3
выдает:
Running main with argc = 4, last = '3'
Running main with argc = 3, last = '2'
Running main with argc = 2, last = '1'
Running main with argc = 1, last = 'testprog'
Однако, поскольку это только неподтвержденное свидетельство, мы должны обратиться к стандарту. Раздел ISO C11 4 Conformance
гласит:
1 / В настоящем международном стандарте «должен» толковаться как требование к реализации или программе; и наоборот, «не должен» должен толковаться как запрет.
2 / Если требование «должен» или «не будет», которое появляется вне ограничения или ограничения времени выполнения, нарушается, поведение не определено. Неопределенное поведение иначе обозначено в этом международном стандарте словами «неопределенное поведение» или пропуском любого явного определения поведения. Нет разницы в акценте между этими тремя; все они описывают «поведение, которое не определено».
3 / Программа, корректная во всех других аспектах, работающая с правильными данными, содержащая неопределенное поведение, должна быть правильной программой и действовать в соответствии с 5.1.2.3.
Теперь, поскольку нигде в стандарте нет явного запрета в стандарте main()
, вызывающем себя, пункт 3 выше является контролирующим аспектом.
Дальнейшую поддержку можно увидеть в двух местах (выделено жирным шрифтом), сначала в разделе 5.1.2.2.3 Program termination
:
1 / Если тип возврата функции main
является типом, совместимым с int
, возврат из начального вызова функции main
эквивалентен к вызову функции exit
со значением, возвращаемым функцией main
в качестве аргумента;
А потом в разделе 7.21.3 Files
:
5 / Файл может быть впоследствии повторно открыт при том же или другом выполнении программы, а его содержимое восстановлено или изменено (если его можно изменить в начале). Если функция main
возвращается к своему исходному абоненту или если вызывается функция exit
, все открытые файлы закрываются (следовательно, все выходные потоки сбрасываются) до завершения программы .
Оба этих подраздела поддерживают возможность того, что другие звонки на main()
могут превышать исходный / оригинальный.