Что будет при рекурсивном вызове функции main???
int main() {
main();
}
Стандарт запрещает использовать функцию main
6.6.1 main function
3. The function main shall not be used within a program. ...
Однако, некоторые компиляторы могут отклоняться от стандартного поведения.
К примеру, возьмем clang 3.8.0
.
С флагом -pedantic-errors
компилятор выдает ошибку:
error: ISO C++ does not allow 'main' to be used by a program
https://rextester.com/QBKCG46413
Однако, если убрать данную опцию, то поведение, возможно, будет неожиданным. Возьмем небольшой код:
#include <iostream>
struct Some
{
Some() { std::cout << "begin" << std::endl; }
~Some() { std::cout << "end" << std::endl; }
};
Some s;
int main()
{
main();
}
Объект s
предназначен просто для вывода сообщений до запуска main
и после её выполнения.
Если собрать это с флагом -O0
, то получаем честный SIGSEGV
: https://rextester.com/XTRATW71243
Однако, уже с флагом -O1
мы видим вывод обоих сообщений и никаких ошибок
begin
end
т.е. main
выполнился успешно: https://rextester.com/XUF23687
Это связано с оптимизациями при неопределенном поведении.
Дело в том, что бесконечная рекурсия без изменения состояния - неопределенное поведение, поэтому компилятор вправе сделать что угодно. В данном случае clang
видит, что рекурсия не меняет внешнее состояние, и имеется всего одна точка выхода - return 0
в конце main
(будет добавлен компилятором автоматически, т.к. в main
отсутствует явный return
), поэтому всю эту рекурсию можно законно удалить:
4.6 Program execution
1. The semantic descriptions in this International Standard define a parameterized nondeterministic abstract machine. This International Standard places no requirement on the structure of conforming implementations. In particular, they need not copy or emulate the structure of the abstract machine. Rather, conforming implementations are required to emulate (only) the observable behavior of the abstract machine as explained below.6
...
6) This provision is sometimes called the “as-if” rule, because an implementation is free to disregard any requirement of this International Standard as long as the result is as if the requirement had been obeyed, as far as can be determined from the observable behavior of the program. For instance, an actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no side effects affecting the observable behavior of the program are produced.
Если посмотреть код функции main после компиляции, то он таков:
main: # @main
xor eax, eax
ret
https://godbolt.org/z/63h1rn
Стандартом языка запрещается любое использование функции main
:
6.6.1 main function [basic.start.main]
3 The function main shall not be used within a program.
Переполнение стека, поскольку нет никакого условия завершения рекурсии...
Кстати, VC++ 2017, например, честно об этом предупреждает. А вот GCC на ideone компилирует без предупреждений.
Функция main
обладает следующими специальными свойствами:
main
зарезервировано в глобальном пространстве имён для функций (хотя это имя может быть использовано для именования классов, пространства имён, перечислений и любых сущностей не в глобальных пространствах имён, за исключением того, что функция с именем 'main'
не может быть объявлена со связыванием для языка C в любом пространстве имён (начиная с C++17)).inline
, static
или constexpr
.main
не обязателен оператор return
: при завершении функции main
без оператора return
эффект будет тот же самый, как при выполнении return 0;
.return
(или неявного return
при достижении конца функции main
) эквивалентно нормальному выходу из функции (которое уничтожает объекты с автоматическим временем жизни) с последующим вызовом std::exit
с тем же самым аргументом, который был передан в return
. (std::exit
уничтожает статические объекты и завершает программу).main
определена как function-try-block
, исключения, брошенные деструкторами статических объектов (которые уничтожаются при вызове std::exit
), не отлавливаются функцией.main
не может быть выведен (auto main() {...}
не разрешён).https://ru.cppreference.com/w/cpp/language/main_function https://en.cppreference.com/w/cpp/language/main_function
Виртуальный выделенный сервер (VDS) становится отличным выбором
Так уж пришлось, что мне нужно сделать задание в C++ builder 6И такой вопрос, как изменить маленькую букву на большую через изменение кода символа
Изучаю работу с файлами в С++ Сделал абсолютно все как в примереВ консоль выводится сообщение Good!, но при этом файл не создается, а если вручную...