4

Я программировал на C некоторое время, и я задавался вопросом, почему важно разделять эти процессы (компиляция и связывание)?Почему важно отделить процессы компиляции и связывания в C?

Может кто-нибудь объяснить, пожалуйста?

+3

Почему, на ваш взгляд, это важно? –

+0

Я вижу, что многие веб-сайты и учебники делают эти процессы отдельно – Luca

ответ

5

Полезно для уменьшения времени восстановления. Если вы меняете только один исходный файл - часто нет необходимости перекомпилировать весь проект, но только один или несколько файлов.

0

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

gcc f1.c f2.c f3.c f4.c -o program 

, который создает исполняемый program из этих исходных файлов.

Но факт остается фактом: это отдельные процессы, и в некоторых случаях это стоит заметить.

2

Поскольку компиляция отвечает за преобразование исходного кода каждого файла исходного кода в соответствующий объектный код. Вот и все. Поэтому компилятор не должен заботиться о ваших внешних символах (таких как библиотеки и переменные extern).

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

Если вы решили использовать инструмент Make, вы увидите, что это не перекомпилировать каждый файл каждый раз, когда вы вызываете make , он находит, какие файлы были изменены с момента последней сборки, а затем перекомпилирует их только. Затем вызывается процесс связывания. Это большая экономия времени при работе с большими проектами (например, linux kernel).

2

Это, наверное, менее важно в эти дни, чем когда-то.

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

Результат был «объектные файлы» - .obj (DOS/Windows/VMS) и .o файлов (UNIX) - которые содержат перемещаемый код, статические данные и списки экспорта (объекты, которые мы уже определили) и импорт (объекты, которые нам нужны). Эталон связывания объединяет все это в исполняемый файл или в архив (.lib, .a, .so, .dll файлов и т. Д.) Для дальнейшего включения.

Выполнение дорогостоящей задачи компиляции в одиночку привело к созданию сложных инкрементных инструментов построения, таких как make, что привело к значительному увеличению производительности программистов - по-прежнему важно для крупных проектов C, таких как ядро ​​Linux.

Также полезно использовать любой язык, который может быть скомпилирован в объектный файл. Таким образом, с небольшим усилием можно связать C с Fortran с COBOL на C++ и так далее.

Многие языки, разработанные с тех пор, подтолкнули границы того, что можно хранить в объектных файлах.Система шаблонов C++ требует специальной обработки, а перегруженные методы не совсем подходят либо как простые файлы .o не поддерживают несколько функций с тем же именем (см. C++ name mangling). Java et al использует совершенно другой подход, с пользовательскими форматами кодовых файлов и механизмом вызова «native code», который склеивает библиотеки DLL и общие файлы объектов.

0

Я работал над системами, где требуется два дня для их компиляции. Вы не хотите делать небольшие изменения, а затем должны ждать 2 дня для тестирования.