Главная функция
Программа должна содержать глобальную функцию с именем main, которая является назначенной точкой входа программы в hosted-среде. Она должна иметь одну из следующих форм:
int main() { body } | (1) | |
int main(int argc, char* argv[]) { body } | (2) | |
int main(/* implementation-defined */) { body } | (3) |
main, выполняющаяся независимо от аргументов, предоставленных средой.main, принимающая аргументы, предоставленные средой.main с определяемым реализацией типом, возвращающая int.main с типом, определяемым реализацией, размещали дополнительные (необязательные) параметры после argv .| argc | - | Неотрицательное значение, представляющее количество аргументов, переданных программе из среды, в которой она выполняется. |
| argv | - | Указатель на первый элемент массива указателей argc + 1, последний из которых является нулевым, а предыдущие, если таковые имеются, указывают на многобайтные строки с нулевым терминатором, представляющие аргументы, переданные программе из среды выполнения. Если argv[0] не является нулевым указателем (или, что эквивалентно, если argc > 0), он указывает на строку, представляющую имя, использованное для вызова программы, или на пустую строку. |
| body | - | Тело функции main. |
Пояснение
Функция main вызывается при запуске программы после инициализации нелокальных объектов со статической длительностью хранения. Она является назначенной точкой входа программы, выполняемой в hosted-среде (то есть с операционной системой). Точки входа автономных программ (загрузчиков, ядер ОС и т. д.) определяются реализацией.
Параметры двухпараметрической формы функции main позволяют передавать произвольные многобайтные символьные строки из среды выполнения (обычно их называют аргументами командной строки); указатели [argv[1], argv[argc - 1]] указывают на первые символы каждой из этих строк. argv[0] (если он не равен нулю) — это указатель на начальный символ многобайтной строки с нулевым терминатором, представляющей имя, использованное для вызова самой программы (или пустую строку "", если такая возможность не поддерживается средой выполнения). Строки можно изменять, однако эти изменения не передаются обратно в среду выполнения: их можно, например, использовать с std::strtok. Размер массива, на который указывает argv, составляет не менее argc + 1, а последний элемент, argv[argc], гарантированно является нулевым указателем.
Функция main обладает несколькими особыми свойствами:
main не обязано содержать return оператор: если управление достигает конца main, не встретив оператора return, это равносильно выполнению return 0;.main) эквивалентно тому, что сначала функция завершается обычным образом (что уничтожает объекты с автоматической длительностью хранения и вычисляет все постусловные утверждения функции main(начиная с C++26)), а затем вызывается std::exit с тем же аргументом, что и у return (std::exit после этого уничтожает статические объекты и завершает программу).Функция main имеет несколько ограничений (их нарушение делает программу некорректной):
main в глобальном пространстве имён зарезервировано для функций (хотя его можно использовать для именования классов, пространств имён, перечислений и любых сущностей в неглобальном пространстве имён, за исключением того, что сущность с именем main нельзя объявлять с связью с языком C ни в каком пространстве имён).| (начиная с C++11) | |
| (начиная с C++20) |
| 4) Её нельзя объявить удалённой. | (начиная с C++11) |
5) Возвращаемый тип функции main нельзя вывести (automain(){...} не допускается). | (начиная с C++14) |
6) Функция main не может быть сопрограммой. 7) Функция main не может быть присоединена к именованному модулю. | (начиная с C++20) |
Примечания
Если функция main определена с помощью функционального try-блока, исключения, выброшенные деструкторами статических объектов (которые уничтожаются неявным вызовом std::exit), не перехватываются им.
Способ преобразования аргументов, переданных в командной строке ОС, в многобайтные символьные массивы, на которые ссылается argv, может включать обработку, определяемую реализацией:
Очень распространённая определяемая реализацией форма main() имеет третий аргумент (помимо argc и argv) типа char**, указывающий на массив указателей на переменные среды выполнения.
Пример
Показывает, как сообщить программе, где найти входные данные и куда записать результаты.
Возможный вызов: ./convert table_in.dat table_out.dat
#include <cstdlib>
#include <iomanip>
#include <iostream>
int main(int argc, char *argv[])
{
std::cout << "argc == " << argc << '\n';
for (int ndx{}; ndx != argc; ++ndx)
std::cout << "argv[" << ndx << "] == " << std::quoted(argv[ndx]) << '\n';
std::cout << "argv[" << argc << "] == "
<< static_cast<void*>(argv[argc]) << '\n';
/* ... */
return argc == 3 ? EXIT_SUCCESS : EXIT_FAILURE; // optional return value
}
Возможный вывод:
argc == 3 argv[0] == "./convert" argv[1] == "table_in.dat" argv[2] == "table_out.dat" argv[3] == 0
Ссылки
| Дополнительное содержимое |
|---|
|
Отчёты об исправлениях
Следующие отчёты об исправлениях, изменяющие поведение, были применены задним числом к ранее опубликованным стандартам C++.
| DR | Применён к | Опубликованное поведение | Корректное поведение |
|---|---|---|---|
| CWG 1003 | C++98 | поддерживаемые имена параметров функции main были чрезмерно ограничены | поддерживаются все допустимые имена параметров |
| CWG 1886 | C++98 | функцию main можно было объявить со связью с языком | запрещено |
| CWG 2479 | C++20 | функцию main можно было объявить как consteval | запрещено |
| CWG 2811 | C++98 | было неясно, используется ли функция main после N3214 | считается используемой при именовании |
| P3618R0 | C++98 | функцию main нельзя было объявить со связью с языком "C++" | разрешено |
См. также
Документация по C о функции main |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
https://en.cppreference.com/cpp/language/main_function