Много лет спустя я обнаружил этот вопрос. Прочитав все ответы и комментарии, я подумал, что смогу уточнить некоторые детали ... Это может быть полезно для людей, которые попадают сюда через поиск в Google.
Вопрос конкретно об использовании функций "extern", поэтому я буду игнорировать использование "extern" с глобальными переменными.
Давайте определим 3 прототипа функций
//--------------------------------------
//Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
int function_3(void);
Заголовочный файл может использоваться основным исходным кодом следующим образом
//--------------------------------------
//Filename: "my_project.C"
#include "my_project.H"
void main(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 1234;
Чтобы скомпилировать и связать, мы должны определить «function_2» в том же файле исходного кода, где мы вызываем эту функцию. Две другие функции могут быть определены в другом исходном коде " .C" или они могут находиться в любом двоичном файле ( .OBJ, * .LIB, * .DLL), для которого у нас может не быть исходный код.
Давайте снова включим заголовок «my_project.H» в другой файл «* .C», чтобы лучше понять разницу.
В том же проекте мы добавляем следующий файл
// --------------------------------------
//Filename: "my_big_project_splitted.C"
#include "my_project.H"
void old_main_test(void){
int v1 = function_1();
int v2 = function_2();
int v3 = function_3();
}
int function_2(void) return 5678;
int function_1(void) return 12;
int function_3(void) return 34;
Важные особенности, на которые следует обратить внимание:
Когда функция определена как «статическая» в заголовочном файле, компилятор / компоновщик должен найти экземпляр функции с таким именем в каждом модуле, который использует этот включаемый файл.
Функция, которая является частью библиотеки C, может быть заменена только в одном модуле путем переопределения прототипа со «статическим» только в этом модуле. Например, замените любой вызов «malloc» и «free», чтобы добавить функцию обнаружения утечек памяти.
Спецификатор extern на самом деле не нужен для функций. Когда «static» не найдено, функция всегда считается «extern».
Однако, extern не является значением по умолчанию для переменных. Обычно любой заголовочный файл, который определяет переменные, которые должны быть видны во многих модулях, должен использовать "extern". Единственное исключение - если заголовочный файл гарантированно будет включен из одного и только одного модуля.
Многие менеджеры проектов тогда требуют, чтобы такая переменная была помещена в начале модуля, а не внутри какого-либо заголовочного файла. Некоторые крупные проекты, такие как эмулятор видеоигры "Mame", даже требуют, чтобы такая переменная появлялась только над первой функцией, использующей их.