Если функции сделаны extern
в заголовочных файлах? Или они extern
по умолчанию?
Например, если я пишу это:
// birthdays.h
struct person find_birthday(const char* name);
или это:
// birthdays.h
extern struct person find_birthday(const char* name);
Из The C Book :
Если объявление содержит extern спецификатор класса хранения, или объявление функции без спецификатор класса хранения (или оба), then:
- Если уже есть видимое объявление этого идентификатора с область файла, результирующая связь такой же, как у видимого декларация;
- иначе результатом будет внешняя ссылка.
Итак, если это единственный раз, когда он объявлен в единице перевода, у него будет внешняя связь.
Нет, функции, объявленные в заголовочных файлах, не нужно объявлять extern
.
Но переменные, определенные в заголовке .h
и затем #included
в нескольких .c
файлах должны быть объявлены extern.
Я никогда не беспокоился о "extern" в моем исходном коде, но некоторые люди это делают. На мой взгляд, наличие extern перед переменными, но не функциями, делает более визуально очевидным, какие объекты являются функциями, а какие - переменными (возможно, включая указатели на функции). Я думаю, что многое, вероятно, зависит от того, как создаются объявления в файле .h и как они соотносятся с основным файлом .c. Обычно я начинаю с ввода прототипов файла .h, а затем копирую / вставляю его в файл .c и добавляю тело функции (отмечая точку с запятой в конце прототипа), так что "extern" необходимо добавить в файл заголовка или удаляется из основного файла .c после копирования / вставки.
Функции, объявленные в заголовках, обычно (если вы не очень стараетесь) extern
. Лично я предпочитаю видеть там явное ключевое слово - но компилятору оно не нужно. Оно напоминает читателям, что это extern
, а поскольку люди более ошибаются, чем компьютеры, я считаю, что напоминание помогает.
С переменными важно использовать ключевое слово extern
(и никакого инициализатора) в заголовочном файле. Следовательно, для симметрии с (очень немногими) глобальными переменными, объявленными в заголовках, я использую extern
и в функции - хотя это строго необязательно.