Я программист уже несколько лет.
Мне всегда говорили (и говорили другим), что вы должны включать в свои файлы .c только те файлы .h, которые вам нужны. Ни больше ни меньше.
Но позвольте мне спросить — ПОЧЕМУ?
Используя сегодняшние компиляторы, я могу включить все файлы h проекта, и это не окажет большого влияния на время компиляции.
Я не говорю о включении файлов OS .h, которые включают много определений, макросов и команд предварительной обработки.
Просто включив один «MyProjectIncludes.h». Это будет только сказать:
#pragma once
#include "module1.h"#include "module2.h"// and so on for all of the modules in the project
Что ты говоришь?
Дело не в том, что время компиляции вашего файла .c занимает больше времени из-за слишком большого количества заголовков. Как вы сказали, включение нескольких дополнительных заголовков вряд ли сильно повлияет на время компиляции этого файла.
Реальная проблема заключается в том, что, как только вы сделаете все ваши файлы .c включающими заголовочный файл «master», то каждый раз, когда вы изменяете любой файл .h, каждый файл .c нужно будет перекомпилировать, из-за того, что вы сделали каждый файл .c зависимым от каждого файла .h. Так что даже если вы делаете что-то безобидное, как добавить новый #define
что будет использоваться только один файл, вы будете принудительно перекомпилировать весь проект. Еще хуже, если вы работаете с командой, и все часто делают изменения в заголовочном файле.
Если время на перестройку всего вашего проекта невелико, например, менее 1 минуты, тогда это не будет иметь большого значения. Я признаю, что я сделал то, что вы предложили в небольших проектах для удобства. Но как только вы начнете работать над большим проектом, на восстановление которого у вас уйдет несколько минут, вы поймете разницу между необходимостью восстановления одного файла и восстановлением всех файлов.
Это повлияет на ваше время сборки. Кроме того, вы рискуете иметь круговая зависимость
В общем случае вам не нужно перекомпилировать модули, если только заголовки, от которых они действительно зависят, не изменены. Для небольших проектов это может не иметь значения, и глобальный файл include_everything.h может сделать ваш проект простым. Но в больших проектах время компиляции может быть очень значительным, и предпочтительно максимально минимизировать межмодульные зависимости. Минимизация включений ненужных заголовков — это только один подход. Использование предварительных объявлений типов, на которые ссылаются только указатели или ссылки, использование шаблонов Pimpl, интерфейсов и фабрик и т. Д., — все эти подходы направлены на уменьшение зависимостей между модулями. Эти шаги не только сокращают время компиляции, но и упрощают тестирование вашей системы и ее общую модификацию.
Отличная, хотя и несколько устаревшая ссылка на эту тему Джон Лакос «Разработка крупномасштабного программного обеспечения».
Конечно, как вы сказали, добавление дополнительных файлов не сильно повредит вашему времени компиляции. Как и то, что вы предлагаете, гораздо удобнее просто сбросить все, используя 1 строку включения.
Но разве вы не чувствуете, что незнакомец мог бы лучше понять ваш код, если бы он точно знал, что .h
файлы, которые вы использовали в определенном .c
файл? Для начала, если в вашем коде были какие-либо ошибки, и эти ошибки были в .h
файлы, они бы точно знали, какие .h
файлы для проверки.