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

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

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

5 ответов


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

имя main не зарезервирован в C++, за исключением функции в глобальном пространстве имен. Вы можете объявлять другие объекты с именем main, включая, среди прочего, классы, переменные, перечисления, функции-члены, и функции, не являющиеся членами глобального пространства имен.

вы можете объявить функцию с именем main как функция-член или в пространстве имен, но такая функция не будет main функция, которая обозначает, где начинается программа.

на main функция не может быть объявлена как static или inline. Он также не может быть перегружен; может быть только одна функция с именем main в глобальном пространстве имен.

на main функция не может использоваться в ваша программа: вам не разрешается вызывать main функция из любого места в вашем коде, и вы не можете взять его адрес.

тип возвращаемого main должно быть int. Другой тип возврата не разрешен (это правило выделено жирным шрифтом, потому что очень часто встречаются неправильные программы, которые объявляют main С типом возврата void; это, вероятно, наиболее часто нарушаемое правило, касающееся ).

есть два заявления 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)

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

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

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

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

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

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


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

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

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

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

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


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


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

Per 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, возвращается определенная реализацией форма состояния неуспешное завершение. В противном случае возвращаемый статус определяется реализацией.