Какова правильная декларация основных?

Какова правильная подпись функции main в С++? Каков правильный тип возвращаемого значения и что означает возврат значения из main? Каковы допустимые типы параметров и каковы их значения?

Является ли это системным? С течением времени эти правила менялись? Что произойдет, если я их нарушу?

Ответ 1

Функция main должна быть объявлена ​​как нечлена-функция в глобальном пространстве имен. Это означает, что она не может быть статической или нестатической функцией-членом класса и не может быть помещена в пространство имен (даже в неназванное пространство имен).

Имя main не зарезервировано в С++, кроме как функция в глобальном пространстве имен. Вы можете объявлять другие объекты с именем 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*[]) на самом деле является только аргументом типа указателя в маскировке, следующие два являются действительными способами записи (2), и оба они означают точно то же самое:

int main(int argc, char* argv[])
int main(int argc, char** argv)

Некоторые реализации могут допускать другие типы и количество параметров; вам нужно будет проверить документацию своей реализации, чтобы увидеть, что она поддерживает.

Ожидается, что

main() будет возвращать ноль, указывая на успех и не равный нулю, чтобы указать отказ. Вам не требуется явно писать оператор return в main(): если вы дадите main() return без явного выражения return, он будет таким же, как если бы вы написали return 0;. Следующие две функции main() имеют одно и то же поведение:

int main() { }
int main() { return 0; }

Есть два макроса: EXIT_SUCCESS и EXIT_FAILURE, определенные в <cstdlib>, которые также могут быть возвращены из main(), чтобы указать успех и неудачу соответственно.

Значение, возвращаемое main(), передается функции exit(), которая завершает работу программы.

Обратите внимание, что все это применимо только при компиляции для размещенной среды (неофициально, в среде, где у вас есть полная стандартная библиотека, и там работает ОС вашей программы). Также возможно скомпилировать С++-программу для автономной среды (например, некоторые типы встроенных систем), и в этом случае запуск и завершение полностью определены для реализации, а функция main() может даже не потребоваться. Если вы пишете С++ для современной настольной ОС, вы компилируете для размещенной среды.

Ответ 2

Из стандартных документов., 3.6.1.2 Основная функция,

Он должен иметь возврат тип типа int, но в противном случае его тип определяется реализацией.. Все реализации должны допускать использование следующих функций: определения main:

int main() { / ... / } и int main(int argc, char* argv[]) { / ... / }

В последнем виде argc должно быть количество аргументов, переданных программе из среды, в которой запускается программа. Если argc отличен от нуля , эти аргументы должны быть предоставлены в argv [0] через argv [argc-1] в качестве указателей на начальные символы многобайтовых строк с нулевым символом.....

Надеюсь, что это поможет.

Ответ 3

Две действующие сети - int main() и int main(int, char*[]). Любая вещь может компилироваться или не компилироваться. Если main явно не возвращает значение, 0 неявно возвращается.

Ответ 4

Точная формулировка последнего опубликованного стандарта (С++ 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)

Ответ 5

Сведения о возвращаемых значениях и их значении

В соответствии с 3.6.1 ([basic.start.main]):

Оператор return в main имеет эффект выхода из функции main (уничтожения любых объектов с автоматической продолжительностью хранения) и вызова std::exit с возвращаемым значением в качестве аргумента. Если элемент управления достигнет конца main, не встречая оператора return, это эффект выполнения

return 0;

Поведение std::exit подробно описано в разделе 18.5 ([support.start.term]) и описывает код состояния:

Наконец, управление возвращается в среду хоста. Если статус равен нулю или EXIT_SUCCESS, возвращается форма завершения успешного завершения статуса. Если статус EXIT_FAILURE, возвращается форма выполнения неудачного завершения статуса. В противном случае возвращаемый статус определяется реализацией.