В *.h заголовочных файлах библиотеки C следует объявить функции
extern void f();
// or only
void f();
- при использовании только в
C - при использовании из
C++.
В *.h заголовочных файлах библиотеки C следует объявить функции
extern void f();
// or only
void f();
CC++.Там [почти] никогда не нужно использовать ключевое слово extern при объявлении функции, либо в C, либо в С++. В C и на С++ все функции имеют внешнюю связь по умолчанию. Странная привычка объявлять функции в заголовочных файлах с extern, вероятно, имеет некоторые исторические корни, но уже десятилетиями она уже неактуальна.
Существует одно исключение из вышеприведенного в C, которое, вероятно, напрямую не связано с тем, о чем вы спрашиваете: на языке C (C99), если в некоторой единицы перевода функция определена как inline, а также объявленный как extern (используется явный extern), тогда встроенное определение этой функции также служит внешним определением. Если в блоке трансляции нет деклараций с явным extern, тогда встроенное определение используется только как "внутреннее" определение.
P.S. В С++ существует такая вещь, как extern "C", но это совершенно другое дело.
В заголовочных файлах библиотеки C следует объявить функции:
extern void f(); // or only void f();
В программе на С++ функции объявляются как функции, не возвращающие значения и не принимающие аргументов.
В программе C функции объявляются как функции, не возвращающие значения и принимающие неопределенный, но не переменный список аргументов.
Чтобы получить значение "без аргументов" в C, используйте один из:
extern void f(void);
void f(void);
То же самое обозначение также означает то же самое в С++, хотя для чистого кода на С++ использование void в списке аргументов не является идиоматическим (не делайте этого в чистом С++-коде).
Трудно, но нормальное правило должно было бы объявить функции С++-кодом как extern "C". Чтобы использовать тот же исходный код для обоих, вам необходимо проверить макрос __cplusplus. Обычно вы делаете что-то вроде:
#ifdef __cplusplus
#define EXTERN_C extern "C"
#define EXTERN_C_BEGIN extern "C" {
#define EXTERN_C_END }
#else
#define EXTERN_C /* Nothing */
#define EXTERN_C_BEGIN /* Nothing */
#define EXTERN_C_END /* Nothing */
#endif
EXTERN_C void f(void);
EXTERN_C_BEGIN
void f(void);
int g(int);
EXTERN_C_END
Параметры и варианты являются многообразными, но заголовок может использоваться как C, так и С++.
Макросы обычно определяются в одном универсальном заголовке, который используется повсюду, а затем конкретный заголовок гарантирует включение заголовка общего назначения, а затем использует соответствующую форму макроса.
Формально, нет необходимости в обозначении extern перед объявлением функции. Однако я использую его в заголовках, чтобы подчеркнуть, что это объявление функции, определяемой извне, и для симметрии с теми (редко) случаями, когда есть глобальная переменная, объявленная в заголовке.
Люди могут и не соглашаются с этим; Я использую локальные правила, но когда я являюсь создателем правил, extern включен в заголовок.
Для общего использования объявляйте как
#ifdef __cplusplus
extern "C" {
#endif
void f(void);
#ifdef __cplusplus
}
#endif
В противном случае extern устарел.
Последнее прекрасно, поскольку это только определение функции, которое сообщает тем, кто включает этот заголовок: "Там есть функция с этим прототипом где-то здесь"
В этом контексте функции явно отличаются от переменных, но это другое дело. Однако убедитесь, что вы не включаете тело функции, если вы не объявляете его "inline" или частью определения класса (С++) или как "функция шаблона" (также С++).
Задание extern в прототипе функции не влияет, поскольку по умолчанию предполагается. Всякий раз, когда компилятор видит прототип, он предполагает, что функция определена где-то в другом (в текущей или другой единицы перевода). Это выполняется для обоих языков.
В следующем потоке есть некоторые полезные комментарии в целом об extern.