#c #file #header
#c #файл #заголовок
Вопрос:
Каков эффект включения файла заголовка, ни одна из функций, объявленных в котором, не используется в исходном файле? Влияет ли это на размер стека и т.д.?
Ответ №1:
Это не окажет никакого эффекта, но увеличит время компиляции и усложнит понимание и поддержку кода. Вы должны включать только те заголовки, которые вам действительно нужны, и удалять те, которые становятся избыточными.
Комментарии:
1. Не могли бы вы, пожалуйста, объяснить, почему это увеличивает время компиляции? Связано ли это с дополнительными затратами на предварительную обработку?
Ответ №2:
Это зависит от того, есть ли в файле заголовка определения или просто объявления.
Это также полностью зависит от реализации, поскольку стандарт ISO C ничего не говорит о том, как все делается на этом уровне. Это описывает только то, как вещи, по-видимому, ведут себя на уровне «виртуальной машины C». Но здесь я рассмотрю наиболее вероятный сценарий.
Такие определения, как int xyzzy;
(или, что еще хуже, char big_honkin_thing[9999999];
), могут занимать место в объектном файле и, если у вас нет особо умного компоновщика, также в исполняемом файле. Я говорю «может», поскольку это зависит от реализации.
Инициализация значения с большей вероятностью гарантирует, что оно сохранено в объекте, а не создано во время выполнения. Но вы, вероятно, обнаружите эффект независимо от этого, либо более крупные объектные / исполняемые файлы, если они созданы во время компиляции, либо (слегка) более медленное время запуска, поскольку больше памяти должно быть инициализировано нулем.
Например, добавление char big[99999] = {'x'};
к файлу заголовка приводит к увеличению размера исполняемого файла с 18K до 118K.
Простые элементы объявления, такие как typedef
и extern
, сами по себе не будут выделять пространство в объекте.
Кроме того, даже без определений время компиляции будет увеличено, поскольку компилятору приходится обрабатывать этот файл заголовка. Но это не окажет никакого влияния на время выполнения (ни на скорость, ни на объем памяти).
Комментарии:
1. Хороший момент; но
char big_honkin_thing[9999999];
, скорее всего, не займет места в двоичном файле (поскольку он не инициализирован).2. @cnicutar, да, так и будет. Объекты продолжительности статического хранения инициализируются всеми нулями. Как я уже сказал, у вас может быть интеллектуальный компоновщик, который понимает, что он не используется, и удаляет его из исполняемого файла, но это было бы справедливо и для явно инициализированных объектов.
3. @paxdiablo
.bss
. Я не думаю, что дело в том, что компоновщик обнаруживает неиспользуемый материал (кстати,ld
ничего не обнаруживает). Речь идет о.bss
vs.data
.4. @cnicutar, извините, я вынужден исправить ошибку. Некоторые компиляторы будут достаточно умны, чтобы выделять материал с нулевым инициализацией во время выполнения, а не сохранять его в объектном файле. Я обновлю ответ, но это проблема реализации, а не C (и, в любом случае, это все еще эффект, хотя и временной, а не пространственный).
5. Совершенно верно. Вопрос в том, есть ли определениям какое-либо место в файле заголовка. За исключением некоторых очень специфических угловых случаев, я бы счел это ошибкой или, по крайней мере, сильным запахом кода.
Ответ №3:
Размер стека определяется вашим компоновщиком. Предположительно, вы на самом деле имеете в виду, является ли передаваемый код больше или нет.
Включение файла заголовка, на объявления которого никогда не ссылаются в этой единице перевода, не повлияет на размер сгенерированных объектов. Конечно, это замедлит компиляцию.
Комментарии:
1. Даже если на объявления не ссылаются, увеличивает ли это размер единицы перевода ? Очевидно, что это не повлияет на конечный размер объекта, как вы упомянули.
Ответ №4:
Это увеличит время компиляции, но AFAIK никаких других изменений быть не должно.
Ответ №5:
Прямой доступ к исходному файлу по сравнению с доступом к исходному файлу с помощью файла заголовка займет меньше времени, если в заголовке нет ничего, что могло бы повлиять на исходный файл.