Nel linguaggio C, l'area di memorizzazione delle variabili determina dove vengono memorizzati i dati, per quanto tempo sono disponibili e quale area di codice può accedervi. Storicamente, le parole chiave auto (di default per le variabili locali), static (mantiene il valore tra le chiamate, spesso usata per mantenere lo stato) ed extern (dichiara una variabile definita altrove) sono state introdotte per controllare la visibilità e il tempo di vita delle variabili.
Problema — una cattiva comprensione di dove e quanto vive una variabile può portare a errori di accesso, perdite di memoria e codice difficile da leggere. Ad esempio, aspettarsi erroneamente che una variabile locale static venga ricreata ad ogni chiamata della funzione, o viceversa, che una variabile auto mantenga il valore tra le chiamate.
Soluzione — scegliere sempre consapevolmente lo specificatore di memorizzazione e comprendere le sue conseguenze:
Esempio di utilizzo:
// main.c int global_var = 42; // ha area di memorizzazione static di default, linkage esterno void func() { static int counter = 0; // vive tra le chiamate auto int temp = 5; // locale, non è necessario specificare auto counter++; printf("call #%d\n", counter); } extern int global_var;
Caratteristiche chiave:
Perché scrivere auto, se le variabili sono automatiche di default?
Risposta: Nelle versioni moderne di C, la parola chiave auto è quasi non utilizzata esplicitamente — per una variabile locale è lo specificatore di default. In generale, la sua scrittura esplicita non offre alcun vantaggio.
È possibile usare static all'interno di una funzione per dichiarare una variabile globale?
Risposta: No, static all'interno di una funzione rende la variabile locale, ma mantiene lo stato tra le chiamate. Non è visibile al di fuori della funzione.
Esempio di codice:
void foo() { static int call_count = 0; // Non è globale, ma vive tra le chiamate call_count++; }
Cosa succede se dichiaro una variabile come extern all'interno di una funzione, ma non la definisco da nessuna parte?
Risposta: Questo porterà a un errore di linker, perché è stata dichiarata una referenza a una variabile globale che non esiste.
In un grande progetto, le variabili-modulo erano dichiarate come extern in tutti i sorgenti, ma si dimenticavano di fare la definizione. Di conseguenza — misteriosi errori di collegamento, poco chiari per i nuovi sviluppatori.
Pro:
Contro:
Definite rigorosamente le aree di visibilità: ogni variabile static solo nel modulo necessario, gli extern globali dichiarati nelle intestazioni e definiti in un solo posto.
Pro:
Contro: