Через багато років я відкриваю це питання. Прочитавши кожну відповідь та коментар, я подумав, що можу уточнити кілька деталей ... Це може бути корисно для людей, які потрапляють сюди через пошук у 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;
Важливі функції, які слід помітити:
Коли функція визначена як "статична" у файлі заголовка, компілятор / лінкер повинен знайти примірник функції з цим ім'ям у кожному модулі, який використовує файл, що включає цей файл.
Функція, що входить до бібліотеки С, може бути замінена лише в одному модулі шляхом повторного визначення прототипу з "статичним" лише в цьому модулі. Наприклад, замініть будь-який виклик на "malloc" і "free", щоб додати функцію виявлення витоку пам'яті.
Специфікатор "extern" дійсно не потрібен для функцій. Коли "статичний" не знайдено, функція завжди вважається "зовнішньою".
Однак "extern" не є типовим для змінних. Зазвичай будь-який файл заголовка, який визначає, що змінні повинні бути видимими для багатьох модулів, повинні використовувати "extern". Єдиним винятком буде, якщо гарантовано включення файлу заголовка з одного і лише одного модуля.
Тоді багато менеджерів проектів вимагають, щоб така змінна була розміщена на початку модуля, а не в будь-якому файлі заголовка. Деякі великі проекти, такі як емулятор відеоігор "Mame", навіть вимагають, щоб така змінна з'явилася лише над першою функцією, що використовує їх.