Заголовочные файлы просто обычные.Препроцессор C обрабатывает директиву #include
s, и компилятор видит предварительно обработанный ввод (но вы можете скопировать и вставить огромное количество кода C, чтобы получить эквивалент #include
),На самом деле препроцессору все равно, если вы #include "foo.h"
или #include "foo.c"
, но последнее часто имеет плохой вкус.Наименование файлов заголовков с суффиксом .h
является просто (очень распространенным) соглашением .
Так что, если у вас есть определение функции в заголовке, включенном в несколько исходных файлов (технически * 1014)* единица перевода с), что определение функции находится в каждой такой единице перевода.
Что произойдет тогда, зависит от определения этой функции (оно должно быть static
или даже лучше static inline
).
На практике вы должны ограничить определения функций в заголовке static
или static inline
.Если вы не объявите static
определение функции void foo(int x) { /* something */ }
в заголовке, который включен в несколько файлов *.c
, у вас будет несколько определений ошибок foo
во время ссылка времени.И основной интерес в размещении определения функции в заголовке - включение встраивания (отсюда подсказка inline
);в противном случае (в обычном случае) вам это не нужно, и вы просто помещаете прототип функции в заголовочный файл, а определение функции - в один ваших *.c
файлов.
Еслиу вас есть короткие и быстрые функции, поэтому было бы разумно определить их как static inline
(поэтому укажите их тела) в заголовочных файлах (но, конечно, это увеличивает время компиляции).В противном случае это не стоит бремени.
Некоторые заголовочные файлы могут иметь длинные макросы (из десятков физических строк, все из которых, кроме последнего, заканчивающегося обратной косой чертой), расширенные до определений функций.Посмотрите на sglib для примера.
Обратите внимание, что inline
сегодня (как register
было в предыдущем десятилетии) просто подсказка для компилятора (для встроенное расширение оптимизация), которое можно игнорировать (также многие оптимизирующие компиляторы 1052 * могут встроить функции без каких-либо комментариев, если они знают тело вызываемой функции).
Не забудьте включить все предупреждения и отладочную информацию. С GCC, используйте gcc -Wall -Wextra -g
, возможно с -Wstrict-prototypes
.Вы можете получить включенные файлы с -H
(и предварительно обработанную форму с -C -E
).
См. Некоторый C ссылочный сайт и стандарт C11 n1570 Больше подробностей.Прочитайте руководство GNU cpp
о предварительной обработке.