Импорт файлов заголовков C вопрос о том, что включено

Я немного запутался в файлах заголовков.

Насколько я понимаю заголовочные файлы в C, такие как #include <windows.h>, включаются только необходимые части в зависимости от того, какие функции используются в программе. Например, если бы в исходном коде была реализована только функция MessageBox(), то из заголовочного файла были бы включены только необходимые части.

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

Это кажется довольно противоречивым, поэтому я надеялся, что кто-нибудь поможет мне разобраться в моих фактах.

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


69
2

Ответы:

Решено

Нет,

если вы включаете файл строки

#include <file.h> // or "file.h"

заменяется содержанием file.h

Пример: https://godbolt.org/z/a3WEP6hdP

Заголовочные файлы не являются библиотеками или объектными файлами. При компоновке компоновщик слинкует только используемую функцию (точнее все функции из используемых сегментов).

Но был бы мой окончательный размер исполняемого файла меньше, если бы я использовал WindowsHModular? Конечно, включая <windows.h> со всеми его сотни, а может быть, тысячи строк раздуют исполняемый?

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


Мое понимание файлов заголовков в C, таких как #include <windows.h>, заключается в том, что включаются только необходимые части в зависимости от того, какие функции используются в программе.

Я думаю, это зависит от того, что вы подразумеваете под «включено». Возможно, вы путаете включение заголовка со связыванием, которое является совершенно отдельным этапом позже в процессе компиляции.

На высоком уровне #include директивы просты. Они предписывают компилятору читать исходный код из другого файла, как если бы он появился вместо директивы. Вот и все. Нет врожденного выбора и выбора разных частей. Подумайте: как компилятор узнает, какие фрагменты вам нужны, прежде чем он обработает остальную часть исходного файла?

Принципиальной разницы между файлами заголовков и «обычными» исходными файлами нет, но стало общепринятым и очень строгим обычаем помещать в заголовки только определенные виды кода, в первую очередь:

  • объявления функций
  • определения макросов
  • struct, union и enum определения типов
  • объявления внешних переменных
  • typedef определения

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

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

Тем не менее, я наткнулся на WindowsHModular на GitHub здесь, который утверждает, что позволяет программисту включать только то, что требуется, поскольку автор GitHub разделил Windows.h на различные модули.

Проблема с Windows.h в том, что он огромный и сложный. Хотя это не имеет значения для скомпилированных программ, это требует от компилятора значительных усилий. Цель разделения Windows.h на отдельные модули — сократить время ЦП и память, необходимые для компиляции программ, позволяя вам опустить кучу объявлений, которые вам все равно не нужны.

На данный момент вам, вероятно, лучше игнорировать WindowsHModular.