Почему связано много объектных файлов вместо одного большого объектного файла?

#c #compiler-construction #linker #object-files

#c #компилятор-конструкция #компоновщик #объектные файлы

Вопрос:

Почему скомпилированные языки программирования (например, C ) настроены на создание множества объектных файлов, которые связаны друг с другом, а не на создание одного большого объекта?

Например (написанный на C , может применяться к любому скомпилированному языку), рассмотрим два файла в проекте main.cpp и auxiliary.cpp . В чем разница между main.cpp и auxiliary.cpp , который компилируется в main.o и auxiliary.o , а затем связывается с main.exe , и main.cpp с #include auxiliary.cpp тем, который компилируется только main.o и связан с main.exe ? Насколько мне известно, это, по крайней мере, на первый взгляд, дало бы тот же результат.

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

Комментарии:

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

2. При использовании команды #include препроцессора исходный код будет отображаться во многих файлах для пользователя, но для компилятора будет отображаться как один файл.

3. Это приведет к излишне долгому времени компиляции.

Ответ №1:

Отдельные модули компиляции, подобные этому, ускоряют компиляцию. Если вы вносите изменения auxilliary.cpp , компилятору нужно только воссоздать auxilliary.o , а не перекомпилировать все. Это становится особенно важным, чем больше проект.

Ответ №2:

Я могу ответить на это риторическим вопросом: почему вы пишете много функций вместо одной большой?

Та же логика применяется на уровне ссылок.

Ответ №3:

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

Теперь подумайте, действительно ли то, что вы просите, имеет смысл: если бы требовалось создать один файл .o, ему пришлось бы объединять результаты компиляции каждого cpp в этот двоичный файл по мере его сборки, эффективно оплачивая стоимость многократного связывания. Кроме того, изменение одной единицы преобразования потребует, чтобы компилятор выяснил, какие из символов в большом объектном файле взяты из исходной версии этой единицы преобразования, удалил их из объекта и добавил новые после перестройки.