Как вызывающая функция использует файл заголовка, чтобы определить, что делать с откомпилированным двоичным файлом?

Насколько я понимаю, заголовочные файлы C ++ (и, я полагаю, C) никогда не компилируются, а просто служат объяснением интерфейса файла C ++, который они описывают.

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

Тем не менее, после компиляции (и до компоновки, я думаю, я не уверен), когда файл hello.c является двоичным машинным кодом, а hello.h по-прежнему C ++, как компилятор / компоновщик знает, как вызвать функцию в двоичном блобе на основании наличия его объявления в заголовочном файле?

Я понимаю такие понятия, как таблицы символов, деревья абстрактного синтаксиса и т. Д. (То есть в прошлом я использовал класс компилятора), но это пробел в моих знаниях).

0

Решение

Реализация hello () предполагает определенное соглашение о вызовах (где находятся параметры в стеке, кто очищает стек, вызывающий или вызываемый, и т. Д.).

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

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

0

Другие решения

Модуль компиляции C / C ++ (файл cpp / файл c) включает все файлы заголовков (как текст) и код.

Заголовочный файл помогает объяснить, как создать инструкцию вызова

 push arg1
push arg2
call _some_function

Если блок компиляции включает _some_function тогда это будет решено во время компиляции.

В противном случае это становится неопределенный символ. Если да, то когда появляется компоновщик, он просматривает все объектные файлы и библиотеки, чтобы разрешить все неопределенные символы.

  • Таким образом, заголовочный файл помогает правильно кодировать сборку.
  • Объектные и библиотечные файлы обеспечивают реализации.

Файлы библиотеки являются необязательными. Когда компоновщик просматривает библиотечный файл, он добавляется только в том случае, если он удовлетворяет некоторому символу, в противном случае он не добавляется в двоичный файл.

Объектные файлы (без учета оптимизации) будут добавлены в двоичный файл полностью.

0

Сборка программы на C ++ состоит из двух этапов: компиляция и компоновка.
Заголовок предназначен для компиляции модуля, который вы пишете. Двоичный файл предназначен для компоновки: он содержит скомпилированный код для метода, определенного в соответствующем заголовке. Заголовок должен соответствовать тому, что уже скомпилировано. Во время ссылки вы узнаете, имеет ли ваш заголовок сигнатуру метода, которая соответствует тому, что было скомпилировано в двоичном файле.

-1