Почему бы явно не #include .c файлы? - PullRequest
0 голосов
/ 13 октября 2018

В программах на C, которые я видел, файлы .h всегда явно включаются с использованием:

#include "some_header_file.h"

С другой стороны, файлы .c очень редко включаются с использованием:

#include "some_c_file.c"

Три вопроса:

  1. Почему разница?

  2. Когда вы отклонитесь от нормы и явно включите файл .c?

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

Ответы [ 3 ]

0 голосов
/ 13 октября 2018
  1. Почему разница?

    Придерживаться модульного подхода к проектированию.

  2. Когда будетвы отклоняетесь от нормы и явно указываете файл .c?

    В основном никогда.

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

    Компоновщику не нужны файлы .c, но файлы .o (например), созданные компилятором (в контексте этого вопроса) из.c файлы.Где находятся эти .o файлы, компоновщик сообщает вызывающему (IDE, makefile, user).

0 голосов
/ 13 октября 2018

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

Рассмотрим файл a.c, который определяет глобальный символ (переменную или функцию)имена A.Предположим, b.c и c.c # включают файл a.c.Если у вас есть Makefile, который компилирует и связывает b.c и c.c и создает приложение, у вас будет сбой компоновщика из-за повторяющихся определений A:

 A     A
 |     |
a.c   a.c
 |     |
b.c   c.c
   \  /
executable

В этомНа графике зависимостей исполняемый файл не может быть построен, если только A не является символом области файла.

Чтобы избежать этого, можно #include всех .c файлов в одном "главном" файле, которыйочень ограниченный дизайн антипаттерна.

0 голосов
/ 13 октября 2018

В заголовочных файлах указывается интерфейс (объявления функций, определения макросов, определения типов и т. Д.), А в файлах .c указывается реализация (определения функций и объектов).

Вы почти никогда не включаете файл .c в другой файл .c, главным образом потому, что он быстро становится кошмаром обслуживания, если два файла .c используют одни и те же символы для разных целей или если вы включили цепочки включений (a.c включает b.c, который включает c.c и т. Д.), И вы получите модуль перевода, который слишком велик для обработки компилятором.Это также означает, что если вы изменяете включенный файл .c, вы должны перекомпилировать все, что включает его, независимо от того, изменился этот код или нет, что делает сборку более длительной, чем должна.

EDIT

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

END EDIT

Отдельная компиляция и компоновка - это хорошо, особенно для больших проектов.

Обычно компоновщики ничего не знают об исходных файлах- в типичной цепочке инструментов программист указывает, где все находится через make-файл или что-то подобное.

...