2015-05-24 3 views
2

Есть ли причина не писать один заголовочный файл, который # включает все другие файлы заголовков и просто # включает один заголовок в каждом файле c?Использование заголовка заголовков вместо повторения

Каждый заголовочный файл настройки #ifndef ... #define ... #endif

Для уточнения дублированные; Я спрашивал о пользовательском коде, а не о системных заголовках, а другой возможный дубликат не имел ответов, которые указывали, почему это не очень хорошая идея.

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

+0

возможно дубликат [правильно ли это просто включить все файлы заголовки? ] (http://stackoverflow.com/questions/8101576/is-it-right-to-simply-include-all-header-files) – usr2564301

+0

Я не думаю, что это дубликат @Jongware, они не спрашивают то же самое ! – gsamaras

+0

[This] (http://stackoverflow.com/questions/5138259/is-it-a-good-idea-to-put-all-of-your-includes-in-one-header-file?rq=1) может быть лучшим кандидатом для дублирования. –

ответ

2

Для нетривиального проекта, сочетание обоих политик часто используется: Один заголовок, который включает в себя часто используемые системные заголовки, как stdbool.h, stdint.h, stdatomic.h и т.д. Как они никогда не меняются, они банкнота значение для восстановления.

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

И тогда у вас есть определенные заголовки, которые представляют ваше дерево зависимостей модулей. Они включаются по мере необходимости. Это не только ускоряет создание (не компилирует) проект, но также может использоваться инструментами doc, такими как doxygen, для автоматического создания дерева зависимостей для документации, поэтому вам не нужно отслеживать каждое изменение вручную. Аналогичный подход может быть использован IDE для быстрого доступа к зависимым заголовкам/модулям.

Одним из недостатков, которые особенно связаны с C, называется загрязнение пространства имен. Поскольку C не позволяет создавать собственные пространства имен, каждый включенный заголовок будет иметь свои символы, добавленные в пространство имен текущего блока компиляции. Для Макросов это может быть еще хуже, поскольку они представляют собой простые текстовые замены с очень ограниченным знанием контекста (для этого также проверяйте inline против function-macro).

+0

Загрязнение «пространства имен» и расширенное время сборки являются двумя основными причинами, чтобы НЕ группировать все заголовки в один файл заголовка. Вся идея make-файлов и т. Д. Заключается в сокращении времени сборки. Я вернулся в те дни, когда сборка могла занимать часы и часы и часы. В те дни (когда программы были намного меньше), мы сделали бы все возможное, чтобы свести к минимуму количество компиляции файлов. Теперь программы намного больше, и компиляция файла обычно происходит почти мгновенно, но когда есть сотни/тысячи файлов, нам все равно нужно сделать все возможное, чтобы свести к минимуму – user3629249

+0

@ user3629249: Вы действительно прочитали мой ответ? Я просто детализировал, чем. Вы, конечно, не думаете, что системные заголовки часто меняются, не так ли? Для некоторых проектов время сборки в основном не имеет отношения к достойному аппаратным средствам хоста, поэтому было бы также нецелесообразно комбинировать некоторые только периодически изменяющиеся заголовки; если они в любом случае включены в большинство модулей. Тогда это не имеет никакого значения. Я думаю, что я четко заявил, когда и когда не использовать какой подход. Я занимаюсь этим бизнесом достаточно долго, чтобы узнать, как это было тогда. И я, конечно, не делаю и не утверждаю _for_ связывание _all_ заголовков. – Olaf

+0

Какой ответ? Я просто все прочитал, и все, что я вижу от вас, - это два комментария, ответа нет. – user3629249

2

Что вы предлагаете: многие проекты используют это соглашение.

Некоторые преимущества:

  • Простота файла заголовка
  • Упрощенные зависимости в Makefile, нет необходимости в сложных списков автоматически сгенерированных зависимостей
  • Раннее обнаружение конфликтов имен.
  • Нет рекурсивного включают
  • головоломки
  • не тонких ошибок из-за разные заказы включают
  • Быстрее компиляции, если вы используете скомпилированные заголовки.

Некоторые недостатки:

  • Любое изменение в заголовочном файле будет вызывать все исходные файлы в проекте перекомпилировать.
  • рекомендует отсутствие надлежащей герметизации
  • Медленнее время компиляции для отдельных файлов (это исправить с скомпилированных заголовков, если это становится проблемой производительности)
3

Причина разобьем заголовочные файлы и файлы реализации в виде отдельных файлов в первое место (помимо читаемости кода) - включить инкрементное построение компилятором. То есть, если мы внесем изменения в HeadearA.h, то только ImplA.c и ImplB.c необходимо, не нужно перекомпилировать ImplC.c через ImplZ.c. Однако, если вы сделаете это по-своему, компилятор не сможет это знать, и вы закончите перекомпиляцию всех файлов .c для каждой перестройки независимо от необходимости. Для небольших проектов с небольшим временем сборки это нормально. Для крупных проектов, которые имеют время сборки около 30 минут, это становится непомерно высоким.

+2

30 минут времени сборки ... звучит как проект C++. – chqrlie

+0

Это; и, честно говоря, самое длинное время, которое я видел для проекта C, составляет около 5 минут, но принцип тот же, я чувствую. –

+0

Такие крупные проекты C довольно редки. Я могу думать о glibc, gcc, X-Windows, ядре Linux ... большинство проектов C восстанавливаются с нуля в секундах на современных машинах с достаточным объемом оперативной памяти. – chqrlie

2

Основная проблема заключается в том, что в конечном итоге вы получаете большую миску кода спагетти, и все знает обо всем. В любом случае. Все, что вы меняете, имеет последствия, и вам в конечном итоге придется рефакторинг для ремодуляции ... You не имеют ни малейшего напоминания о том, что на самом деле есть какой-то заголовок, чтобы решение x должно было знать о y.

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

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