Main() перегружен в C++?
2 действительные версии main()
существуют в C++
:
int main() // version 1
int main(int argc, char **argv) // version 2
Но обе перегрузки не могут сосуществовать одновременно. Почему бы и нет? (Возможный вариант использования: при запуске программы из терминала, если аргументы не переданы, вызывается первая версия, в противном случае - вторая версия.)
Компилятор выполняет специальную проверку, чтобы разрешить только одну версию для двоичного файла?
6 ответов
§3.6.1/2 (C++03) говорит
Реализация не должна предопределять
main
функция. Эта функция не должна быть перегружена. Он должен иметь возвращаемый тип типа int, но в остальном его тип определяется реализацией. Все реализации должны позволять оба следующих определения main:
int main() { /* ... */ }
int main(int argc, char* argv[]) { /* ... */ }
Вы можете использовать любой из них. Оба соответствуют стандарту.
Кроме того, так как char *argv[]
эквивалентно char **argv
, заменяя char *argv[]
с char **argv
не имеет никакого значения.
Но обе версии не могут сосуществовать одновременно! (вариант использования может быть таким: при запуске двоичного файла из командной строки, если вы не передаете аргумент, тогда 1-ую версию следует называть, а 2-ую версию).
Нет. Обе версии не могут сосуществовать одновременно. Одна программа может иметь ровно одну main
функция. Какой, зависит от вашего выбора. Если вы хотите обработать аргумент командной строки, вам нужно выбрать вторую версию, иначе достаточно первой версии. Также обратите внимание, что если вы используете вторую версию и не передаете аргумент командной строки, то в этом нет никакого вреда. Это не вызовет никакой ошибки. Вы просто должны интерпретировать argc
а также argv
соответственно, и исходя из их ценности, вы должны написать логику и последовательность действий вашей программы.
Windows и Unix имеют:
int main(int argc, char **argv, char **envp)
и приложения Win32 имеют:
int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow);
и MacOS имеет:
int main(int argc, char **argv, char **envp, char **apple)
Не забывай это main
ОС обычно не первое, что вызывает ОС при выполнении программы. main
Функция - это функция, которая вызывается средой выполнения. Адрес первой выполняемой инструкции обычно объявляется в некоторых метаданных, обычно в начале исполняемого файла.
Насколько я могу судить, ничто из вышеперечисленного не противоречит стандарту C/C++, если есть только один, что имеет смысл, поскольку ОС не будет знать, куда обращаться, если их было больше одного. Проверка только одного не выполняется в компиляторе, это делается в компоновщике.
Раздел 3.6.1.2 обоих выпусков C++ Standard 1998 и 2003 гласит:
Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена. Он должен иметь возвращаемый тип типа int, но в остальном его тип определяется реализацией.
В дальнейшем,
Стандарт ISO C++ (ISO/IEC 14882:1998) специально требует, чтобы main возвращал int. У этого есть явное ограничение "должен" на хорошо сформированные программы.
Раздел § 3.6.1 ¶ 2:
Он должен иметь возвращаемый тип int, но в остальном его тип определяется реализацией. Все реализации должны позволять оба следующих определения main:
int main() { /* … */ }
а также
int main(int argc, char* argv[]) { /* … */ }
Так что обе версии main
разрешены стандартом и какой из них оставлен в качестве предпочтения реализации программиста.
Главное было определено еще в C дней. Это больше похоже на правила printf. Рассматривать main
как бродячая функция:
int main(...)
Стандарт гласит, что без аргументов и двух аргументов указателя все в порядке. Однако, если реализация хочет предоставить больше аргументов, реализация может сделать это бесплатно.
Причина, по которой вы не можете иметь два main
s та же самая причина, по которой вы не можете определить printf
как функция дважды в программе на Си. Конечно, printf
поддерживает разные аргументы и меняет его поведение в зависимости от того, какие аргументы есть, но это не перегрузка в смысле C++ термина.
Стандарт говорит, что main
не может быть перегружен. Он не искажен, и вы не можете иметь две функции с одним и тем же именем. Я полагаю, что это приведет к сбою компоновки, но компилятор может захотеть добавить явные проверки для более четких сообщений об ошибках.
int main(int argc, char **argv)
а также int main()
должны быть предпочтительными сигнатурами для него, но компиляторы могут свободно принимать main
с разными параметрами.
Невозможно перегрузить main() в C++, потому что. компилятор показал следующую ошибку:
error C2731: 'main' : function cannot be overloaded