Является ли main () перегруженным в C ++? - PullRequest
67 голосов
/ 20 июня 2011

2 допустимые версии main() существуют в C++:

int main()  // version 1
int main(int argc, char **argv)  // version 2

Но обе перегрузки не могут сосуществовать одновременно.Почему бы и нет?(Возможный вариант использования: при запуске программы из терминала, если не переданы аргументы, вызывается первая версия, в противном случае - вторая версия.)

Выполняет ли компилятор специальную проверку, чтобы разрешить только одну версиюдвоичная?

Ответы [ 6 ]

65 голосов
/ 20 июня 2011

§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 соответственно, и, основываясь на их значении, вы должны написать логику и последовательность вашей программы.

20 голосов
/ 20 июня 2011

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)

Не забывайте это1010 * обычно не первое, что вызывает ОС при выполнении программы.Функция main - это функция, вызываемая средой выполнения.Адрес первой выполняемой инструкции обычно объявляется в некоторых метаданных, обычно в начале, если исполняемый файл.

Ничто из вышеперечисленного не противоречит стандарту C / C ++, насколько я могу судить, покапоскольку есть только один, что имеет смысл, так как ОС не будет знать, куда звонить, если их было больше одного.Проверка только одного не выполняется в компиляторе, это делается в компоновщике.

13 голосов
/ 20 июня 2011

В разделе 3.6.1.2 редакций C ++ Standard 1998 и 2003 годов говорится:

Реализация не должна предопределять основную функцию. Эта функция не должна быть перегружена .Он должен иметь возвращаемый тип типа int, но в остальном его тип определяется реализацией.

Далее,

Стандарт ISO C ++ (ISO / IEC 14882: 1998) специально требуетглавное вернуть int.У этого есть явное ограничение "должен" на хорошо сформированные программы.

Раздел § 3.6.1 ¶ 2:

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

int main() { /* … */ }

и

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

Таким образом, обе версии main разрешены стандартом и какаяИспользование оставляется в качестве предпочтения реализации программиста.

9 голосов
/ 20 июня 2011

Main был определен еще в C дней. Это больше похоже на правила printf. Рассмотрим main как случайную функцию:

int main(...)

Стандарт говорит, что без аргументов и двух аргументов-указателей все в порядке. Однако, если реализация хочет предоставить больше аргументов, реализация может сделать это бесплатно.

Причина, по которой у вас не может быть двух main s, та же самая причина, по которой вы не можете дважды определить printf подобную функцию в программе на Си. Конечно, printf поддерживает разные аргументы и меняет свое поведение в зависимости от того, какие аргументы есть, но это не перегрузка в смысле C ++ термина.

7 голосов
/ 20 июня 2011

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

int main(int argc, char **argv) и int main() должны быть предпочтительными сигнатурами для него, но компиляторыВы можете принять main с другими параметрами.

0 голосов
/ 20 июня 2011

Невозможно перегрузить main () в C ++, потому что.компилятор показал следующую ошибку:

error C2731: 'main' : function cannot be overloaded 
...