Две основных функции

Мы можем иметь два main() функции в программе C++?

6
задан Prasoon Saurav 13 April 2010 в 02:13
поделиться

8 ответов

Стандарт прямо говорит в 3.6.1:

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

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

19
ответ дан 8 December 2019 в 02:07
поделиться

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

int main(int argc, char ** argv)
{
   if (argc > 0)  // paranoia
   {
           if (strstr(argv[0], "frogger")) return frogger_main(argc, argv);
      else if (strstr(argv[0], "pacman"))  return pacman_main(argc, argv);
      else if (strstr(argv[0], "tempest")) return tempest_main(argc, argv);
   }

   printf("Hmm, I'm not sure what I should run.\n");
   return 10;
}

... затем просто переименуйте свои «другие» функции main () в frogger_main (), pacman_main () или любые другие имена, которые вы хотите им дать, и у вас будет программа, которая запускается как Frogger, если в имени исполняемого файла есть слово 'frogger', или запускается как PacMan, если исполняемый файл имеет имя 'pacman' в это и т. д.

3
ответ дан 8 December 2019 в 02:07
поделиться

в глобальной области существует только одна точка входа.

0
ответ дан 8 December 2019 в 02:07
поделиться

Да! Почему бы и нет?

Рассмотрим следующий код:

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

 int main()
 {
     ps::main();
 }

Его :: main () , который будет вызываться во время выполнения.

8
ответ дан 8 December 2019 в 02:07
поделиться

Вы не можете перегрузить main () в глобальной области.

4
ответ дан 8 December 2019 в 02:07
поделиться

Только одна функция может иметь имя main вне любого пространства имен, как и любое другое имя. Если у вас есть пространства имен foo и bar (и т.д.), вы вполне можете иметь функции с именами foo :: main , bar :: main и т. д., но они не будут рассматриваться как что-то особенное с точки зрения системы (только функция с именем main вне любого пространства имен обрабатывается отдельно как точка входа в программу). Конечно, из вашего main вы могли бы прекрасно вызывать различные foo :: main , bar :: main и так далее.

11
ответ дан 8 December 2019 в 02:07
поделиться

В одной программе разрешена только одна точка входа.

2
ответ дан 8 December 2019 в 02:07
поделиться

Ох, вопрос с подвохом!

Краткий ответ: «Это зависит».

Длинный ответ: как указывали другие, у вас может быть несколько функций с именем main , если они находятся в разных пространствах имен, и только ] main в корневом пространстве имен (т.е. :: main ) используется как основная программа. Фактически, классы потоков некоторых библиотек потоков имеют метод с именем main , который пользователь библиотеки переопределяет кодом, который он хочет запустить в потоке.

Предполагая, что вы не делаете никаких трюков с пространством имен, если вы попытаетесь определить :: main в двух разных файлах .cpp , оба файла будут компилироваться, однако , компоновщик будет прерван, так как есть два определения с именем main ; он не может сказать, на что нужно ссылаться.

(У меня вопрос к гуру: в C ++ выполните определения функций int main () {} и extern "C" int main () {} генерировать функции с такой же сигнатурой? Я сам не пробовал.)

А теперь на время вы можете иметь более одного :: main в исходном коде вашей программы : если один main находится в библиотеке (файл .a или .so), а другой находится в ваших исходных (.o) файлах, то выигрывает тот, который находится в ваших источниках, а тот, который находится в библиотеке, удаляется, и связывание завершается успешно , если нет других проблем! Если бы вы не написали main , библиотека main выиграла бы. Фактически это делается в библиотеках поддержки, которые поставляются с lex и yacc ; они предоставляют barebones main , поэтому вам не нужно писать его для быстрого синтаксического анализа.

Это приводит к интересному приложению: предоставление main каждой библиотеке. Мои библиотеки, как правило, небольшие и целенаправленные, поэтому я помещаю main.cpp в каждую с main , который является тестовым или служебным кодом для библиотеки. Например, в моей библиотеке с общей памятью есть main , который позволяет вызывать все функции для управления общей памятью из командной строки. Затем я могу протестировать множество случаев с помощью сценария bash . Все, что связано с библиотекой разделяемой памяти, получает тестовый код бесплатно или может избавиться от него, просто определив свой собственный main .

РЕДАКТИРОВАТЬ: Чтобы люди понимали концепцию, я говорю о сборке, которая выглядит так:

gcc -c -o bar_main.o bar_main.cpp
ar -r libbar.a bar_main.o
ranlib libbar.a
gcc -c -o foo_main.o foo_main.cpp
gcc -o foo foo_main.o -L. -lbar

В этом примере main в foo_main.o превосходит main в bar_main.o . Стандарт не определяет такое поведение, потому что им все равно. В любом случае люди используют множество нестандартных вещей; Linux является примером использования битовых полей C. ld работает таким образом дольше, чем я умею печатать.

Серьезно, ребята, не стесняйтесь строго придерживаться стандартов, если вам нужно получить код с наименьшим общим знаменателем. Но если у вас есть возможность работать над платформой, которая может создавать программы lex и yacc , во что бы то ни стало, подумайте о том, чтобы воспользоваться этим.

1
ответ дан 8 December 2019 в 02:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: