Plusieurs années plus tard, je découvre cette question. Après avoir lu chaque réponse et commentaire, j'ai pensé pouvoir clarifier quelques détails ... Cela pourrait être utile pour les personnes qui arrivent ici via la recherche Google.
La question concerne spécifiquement l'utilisation des fonctions "extern", donc j'ignorerai l'utilisation de "extern" avec des variables globales.
Définissons 3 prototypes de fonctions:
//--------------------------------------
//Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
int function_3(void);
Le fichier d'en-tête peut être utilisé par le code source principal comme suit:
//--------------------------------------
//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;
Afin de compiler et de lier, nous devons définir "function_2" dans le même fichier de code source où nous appelons cette fonction. Les deux autres fonctions peuvent être définies dans un code source différent " .C" ou peuvent se trouver dans n'importe quel fichier binaire ( .OBJ, * .LIB, * .DLL), pour lequel nous n'avons peut-être pas le code source.
Incluons à nouveau l'en-tête "mon_projet.H" dans un autre fichier "* .C" pour mieux comprendre la différence. Dans le même projet, nous ajoutons le fichier suivant:
//--------------------------------------
//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;
Caractéristiques importantes à noter:
Lorsqu'une fonction est définie comme "statique" dans un fichier d'en-tête, le compilateur / éditeur de liens doit trouver une instance d'une fonction portant ce nom dans chaque module qui utilise ce fichier d'inclusion.
Une fonction qui fait partie de la bibliothèque C peut être remplacée dans un seul module en redéfinissant un prototype avec "statique" uniquement dans ce module. Par exemple, remplacez tout appel à «malloc» et «free» pour ajouter une fonction de détection de fuite de mémoire.
Le spécificateur "extern" n'est pas vraiment nécessaire pour les fonctions. Lorsque "statique" n'est pas trouvé, une fonction est toujours supposée être "externe".
Cependant, "extern" n'est pas la valeur par défaut pour les variables. Normalement, tout fichier d'en-tête qui définit les variables pour être visible sur de nombreux modules doit utiliser "extern". La seule exception serait si un fichier d'en-tête est garanti d'être inclus à partir d'un et d'un seul module.
De nombreux chefs de projet exigeraient alors que cette variable soit placée au début du module, et non dans un fichier d'en-tête. Certains grands projets, comme l'émulateur de jeu vidéo "Mame", exigent même que cette variable n'apparaisse qu'au-dessus de la première fonction qui les utilise.