Спустя много лет я обнаруживаю этот вопрос. Прочитав каждый ответ и комментарий, я подумал, что смогу уточнить некоторые детали ... Это может быть полезно для людей, которые попадают сюда через поиск в Google.
Речь идет конкретно об использовании «внешних» функций, поэтому я буду игнорировать использование «внешних» с глобальными переменными.
Давайте определим 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, может быть заменена только в одном модуле путем переопределения прототипа на «static» только в этом модуле. Например, замените любой вызов «malloc» и «free», чтобы добавить функцию обнаружения утечки памяти.
Спецификатор "extern" на самом деле не нужен для функций. Когда «статический» не найден, функция всегда считается «внешней».
Однако «extern» не является значением по умолчанию для переменных. Обычно любой заголовочный файл, который определяет переменные, которые должны быть видны во многих модулях, должен использовать «extern». Единственное исключение будет, если заголовочный файл гарантированно будет включен из одного и только одного модуля.
Многие менеджеры проектов тогда требуют, чтобы такая переменная была помещена в начале модуля, а не внутри какого-либо заголовочного файла. Некоторые крупные проекты, такие как эмулятор видеоигры «Mame», даже требуют, чтобы такая переменная появлялась только над первой функцией, использующей их.