Что такое правильное объявление основного?
Какова правильная подпись main
функция в C++? Каков правильный тип возвращаемого значения и что означает возвращать значение из main
? Каковы допустимые типы параметров и каковы их значения?
Это зависит от системы? Изменились ли эти правила с течением времени? Что произойдет, если я нарушу их?
5 ответов
main
Функция должна быть объявлена как функция, не являющаяся членом в глобальном пространстве имен. Это означает, что она не может быть статической или нестатической функцией-членом класса, а также не может быть помещена в пространство имен (даже в безымянное пространство имен).
Имя main
не зарезервирован в C++ за исключением функции в глобальном пространстве имен. Вы можете объявить другие лица, названные main
включая, среди прочего, классы, переменные, перечисления, функции-члены и функции, не являющиеся членами, не входящие в глобальное пространство имен.
Вы можете объявить функцию с именем main
в качестве функции-члена или в пространстве имен, но такая функция не будет main
функция, которая определяет, где начинается программа.
main
функция не может быть объявлена как static
или же inline
, Это также не может быть перегружено; может быть только одна функция с именем main
в глобальном пространстве имен.
main
функция не может быть использована в вашей программе: вам не разрешено вызывать main
функционировать из любого места в вашем коде, и вы не можете взять его адрес.
Тип возврата main
должно быть int
, Никакой другой тип возврата не разрешен (это правило выделено жирным шрифтом, потому что очень часто встречаются неправильные программы, которые main
с типом возврата void
; это, вероятно, наиболее часто нарушаемое правило, касающееся main
функция).
Есть две декларации main
это должно быть разрешено:
int main() // (1)
int main(int, char*[]) // (2)
В (1) нет параметров.
В (2) есть два параметра, и они условно названы argc
а также argv
соответственно. argv
является указателем на массив строк C, представляющих аргументы программы. argc
количество аргументов в argv
массив.
Обычно, argv[0]
содержит название программы, но это не всегда так. argv[argc]
гарантированно будет нулевым указателем.
Обратите внимание, что, поскольку аргумент типа массива (как char*[]
) на самом деле является замаскированным аргументом типа указателя, следующие два являются допустимыми способами write (2), и оба они означают одно и то же:
int main(int argc, char* argv[])
int main(int argc, char** argv)
Некоторые реализации могут разрешать другие типы и числа параметров; вам нужно проверить документацию вашей реализации, чтобы увидеть, что она поддерживает.
main()
как ожидается, вернет ноль, чтобы указать успех и ненулевое, чтобы указать сбой. Вы не обязаны явно писать return
заявление в main()
: если позволите main()
вернуть без явного return
заявление, это так же, как если бы вы написали return 0;
, Следующие два main()
функции имеют одинаковое поведение:
int main() { }
int main() { return 0; }
Есть два макроса, EXIT_SUCCESS
а также EXIT_FAILURE
, определенный в <cstdlib>
которые также могут быть возвращены из main()
для обозначения успеха и неудачи соответственно.
Значение, возвращаемое main()
передается в exit()
функция, которая завершает программу.
Обратите внимание, что все это применимо только при компиляции для размещенной среды (неофициально, среды, в которой у вас есть полная стандартная библиотека и есть ОС, выполняющая вашу программу). Также возможно скомпилировать программу на C++ для автономной среды (например, некоторых типов встроенных систем), когда запуск и завершение полностью определяются реализацией, и main()
функция может даже не потребоваться. Если вы пишете C++ для современной настольной ОС, вы компилируете для размещенной среды.
Из стандартных документов. 3.6.1.2 Основная функция,
Он должен иметь возвращаемый тип типа int, но в остальном его тип определяется реализацией. Все реализации должны позволять оба следующих определения main:
int main() { / ... / }
а такжеint main(int argc, char* argv[]) { / ... / }
В последнем виде
argc
должно быть числом аргументов, переданных программе из среды, в которой она запущена. Если argc не равен нулю, эти аргументы должны быть переданы в argv[0] через argv[argc-1] в качестве указателей на начальные символы null- завершенные многобайтовые строки.....
Надеюсь, это поможет..
Точная формулировка последнего опубликованного стандарта (C++14):
Реализация должна позволять как
функция
()
возвратеint
а такжефункция
(int
указатель на указатель наchar)
возвратеint
как тип
main
,
Это дает понять, что альтернативные варианты написания разрешены, если тип main
это тип int()
или же int(int, char**)
, Таким образом, следующие также разрешены:
int main(void)
auto main() -> int
int main ( )
signed int main()
typedef char **a; typedef int b, e; e main(b d, a c)
Две действительные сети int main()
а также int main(int, char*[])
, Любая вещь может компилироваться или не компилироваться. Если main
не возвращает явно значение, 0 неявно возвращается.
Подробности о возвращаемых значениях и их значении
Согласно 3.6.1 ([basic.start.main]
):
Заявление о возврате в
main
имеет эффект оставленияmain
функция (уничтожение любых объектов с автоматической продолжительностью хранения) и вызовstd::exit
с возвращаемым значением в качестве аргумента. Если контроль достигает концаmain
не встречаяreturn
утверждение, эффект заключается в выполненииreturn 0;
Поведение std::exit
подробно описано в разделе 18.5 ([support.start.term]
) и описывает код состояния:
Наконец, управление возвращается в среду хоста. Если статус равен нулю или
EXIT_SUCCESS
возвращается заданная реализацией форма успешного завершения статуса. Если статусEXIT_FAILURE
возвращается форма реализации неудачного завершения статуса. В противном случае возвращаемый статус определяется реализацией.