2015-06-26 4 views
-2

Я работаю над проектом, который содержит несколько модулей (исходные файлы, файлы заголовков, библиотеки). Один из файлов во всем этом супе содержит мою основную функцию.Как компилятор знает, где моя основная функция?

Мои вопросы:

  • Как компилятор знает, какие модули для компиляции и которые не?
  • Как компилятор распознает модуль с основным() внутри?
+0

Читайте о фазах компилятора, и вы получите ответ. – haccks

+0

Это не так. [enuf characters для этого комментария] –

+0

Компилятор не заботится о главной функции и будет компилировать весь блок компиляции. Более поздний компоновщик свяжет их и может удалить несвязанные функции. –

ответ

0

Как компилятор знает, какие модули для компиляции и которые не?

Это не так. Вы говорите ему какие вы хотите скомпилировать, как правило, в том случае, если в make-файле содержатся утверждения (ы) компиляции.

Как компилятор распознает модуль с главным() внутри?

В целом это большой процесс, уже ответил на this related question.

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

Таким образом, чтобы ответить

Как компилятор знает, где моя основная функция?

Необходимо (и не нужно). В частности, это работа линкера.

1

Сам компилятор не заботится о том, какой файл содержит какие функции; main() не является особенным. Однако на этапе связывания все эти символы из разных файлов (и блоков компиляции, возможно) совпадают. У компоновщика есть скрытый «шаблон», который имеет код на фиксированном адресе, который ОС всегда будет вызывать при запуске программы. Этот код вызовет ваш номер main; следовательно, компоновщик ищет main во всех файлах. Если его нет, вы получите неразрешенную ошибку символа, точно так же, как если бы вы использовали функцию, которую вы забыли реализовать.

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

+0

Более конкретно: когда компилятор вызывается в режиме привязки, он действует как драйвер, который ссылается на специальный код времени выполнения библиотеки C. Фиксированный адрес в исполняемом заголовке обычно является адресом символа, называемого '_start'. – o11c

0

Код сборки (часто называемый кодом запуска встроенными людьми), который запускает программу, специально вызывает main().
Прототип для main() включен в документацию компилятора. При компиляции программы создается объектный файл. Объектный файл из вашего исходного кода затем связан с компонентом времени запуска (обычно называемым crt0.o [bj]) и компонентами библиотеки C и т. Д. Если номер main() изменен на неузнаваемую подпись, блок компиляции будет жаловаться на неразрешенная внешняя ссылка на _main или __main.

Смежные вопросы