Molti anni dopo, scopro questa domanda. Dopo aver letto ogni risposta e commento, ho pensato di poter chiarire alcuni dettagli ... Questo potrebbe essere utile per le persone che arrivano qui tramite la ricerca di Google.
La domanda riguarda in particolare l'uso delle funzioni "extern", quindi ignorerò l'uso di "extern" con le variabili globali.
Definiamo 3 prototipi di funzioni:
//--------------------------------------
//Filename: "my_project.H"
extern int function_1(void);
static int function_2(void);
int function_3(void);
Il file di intestazione può essere utilizzato dal codice sorgente principale come segue:
//--------------------------------------
//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;
Per compilare e collegare, dobbiamo definire "function_2" nello stesso file di codice sorgente in cui chiamiamo quella funzione. Le altre due funzioni potrebbero essere definite in diversi codici sorgente " .C" oppure potrebbero trovarsi in qualsiasi file binario ( .OBJ, * .LIB, * .DLL), per il quale potremmo non avere il codice sorgente.
Includiamo di nuovo l'intestazione "my_project.H" in un diverso file "* .C" per comprendere meglio la differenza. Nello stesso progetto, aggiungiamo il seguente file:
//--------------------------------------
//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;
Caratteristiche importanti da notare:
Quando una funzione viene definita "statica" in un file di intestazione, il compilatore / linker deve trovare un'istanza di una funzione con quel nome in ciascun modulo che utilizza quel file di inclusione.
Una funzione che fa parte della libreria C può essere sostituita in un solo modulo ridefinendo un prototipo con "statico" solo in quel modulo. Ad esempio, sostituire qualsiasi chiamata a "malloc" e "free" per aggiungere la funzione di rilevamento delle perdite di memoria.
Lo specificatore "extern" non è realmente necessario per le funzioni. Quando non viene trovato "statico", si presume sempre che una funzione sia "esterna".
Tuttavia, "extern" non è l'impostazione predefinita per le variabili. Normalmente, qualsiasi file di intestazione che definisce le variabili per essere visibili su molti moduli deve usare "extern". L'unica eccezione sarebbe se un file di intestazione è garantito per essere incluso da uno e un solo modulo.
Molti project manager richiedono quindi che tale variabile venga posizionata all'inizio del modulo, non all'interno di alcun file di intestazione. Alcuni grandi progetti, come l'emulatore di videogiochi "Mame", richiedono anche che tale variabile appaia solo sopra la prima funzione che li utilizza.