Ох, вопрос с подвохом!
Краткий ответ: "Это зависит".
Длинный ответ: Как уже отмечали другие, вы можете иметь несколько функций с именем main
, если онинаходятся в разных пространствах имен, и в качестве основной программы используется только main
в корневом пространстве имен (т.е. ::main
).На самом деле, классы потоков некоторых потоковых библиотек имеют метод с именем main
, который пользователь библиотеки переопределяет с помощью кода, который он хочет запустить в потоке.
Теперь, если вы не делаете никаких трюков с пространством имен, есливы пытаетесь определить ::main
в двух разных .cpp
файлах, оба файла сами будут скомпилированы, однако компоновщик прервется, поскольку есть два определения с именем main
;он не может сказать, на какую ссылку связать.
(У меня есть вопрос к гуру: в C ++ определения функций int main() {}
и extern "C" int main() {}
генерируют функции с одинаковой сигнатурой? У меня нет 'Я сам не пробовал.)
А теперь на время у вас может быть более одного ::main
в источнике вашей программы : если один main
находится в библиотеке (.a или.so файл), а другой находится в ваших исходных (.o) файлах, тот, что в ваших источниках, побеждает, а тот, что в библиотеке, удаляется, , и связывание успешно , если нет какой-либо другой проблемы!Если бы вы не написали main
, библиотека main
выиграет.На самом деле это делается в библиотеках поддержки, которые поставляются с lex
и yacc
;они предоставляют скелеты 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 является примером использования битовых полей Си.ld
работал таким образом дольше, чем я знал, как печатать.
Серьезно, ребята, не стесняйтесь строго придерживаться стандартов, если вам нужен код наименьшего общего знаменателя.Но если у вас есть возможность работать на платформе, которая может создавать программы lex
и yacc
, во что бы то ни стало, рассмотрите возможность воспользоваться этим.