Должны ли функции быть сделаны "extern" в заголовочных файлах? - PullRequest
39 голосов
/ 30 июля 2010

Должны ли функции быть сделаны extern в заголовочных файлах?Или они extern по умолчанию?

Например, я должен написать это:

// birthdays.h
struct person find_birthday(const char* name);

или это:

// birthdays.h
extern struct person find_birthday(const char* name);

Ответы [ 5 ]

19 голосов
/ 30 июля 2010

С Книга C :

Если объявление содержит спецификатор класса хранения extern или является объявлением функции без спецификатора класса хранения (или обоих),затем:

  • Если уже есть видимое объявление этого идентификатора с областью видимости файла, результирующая связь такая же, как и у видимой декларации;
  • , в противном случае результатом является внешняя связь.

Так что, если это единственный раз, когда он объявлен в единице перевода, он будет иметь внешнюю связь.

14 голосов
/ 30 июля 2010

Они неявно объявлены как "extern".

13 голосов
/ 30 июля 2010

Функции, объявленные в заголовках, обычно (если вы не очень усердно работаете) extern. Лично я предпочитаю видеть явное ключевое слово там - но компилятору это не нужно. Это напоминает читателям, что они extern, и поскольку люди более подвержены ошибкам, чем компьютеры, я считаю, что напоминание помогает.

Для переменных важно использовать ключевое слово extern (без инициализатора) в файле заголовка. Следовательно, для симметрии с (очень немногими) глобальными переменными, объявленными в заголовках, я также использую extern с функцией - хотя это строго не обязательно.

9 голосов
/ 30 июля 2010

Нет, функции, объявленные в заголовочных файлах, не должны быть объявлены extern.

Но переменные, определенные в .h заголовке и затем #included в нескольких .c файлах , должны быть объявлены extern .

2 голосов
/ 30 июля 2010

Я никогда не беспокоюсь о "extern" в моем исходном коде, но некоторые люди делают.На мой взгляд, наличие перед переменными, но не перед функциями, делает более наглядным, какие вещи являются функциями, а какие переменными (возможно, включая указатели на функции).Я думаю, что многое, вероятно, зависит от того, как создаются объявления в файле .h, и как они связаны с основным файлом .c.Я обычно начинаю с того, что набираю прототипы файла .h, а затем копирую / вставляю в файл .c и добавляю тело функции (ставя точку с запятой в конце прототипа).файл заголовка или вычеркнутый из основного файла .c после копирования / вставки.

...