static (a livello di file/modulo):
static, la visibilità è limitata al modulo in compilazione (file).extern:
Importante: static — per nascondere l'implementazione, extern — per il collegamento tra i moduli.
Esempio:
main.c:
static int hidden_var = 5; extern int shared_var; int main() { printf("shared %d", shared_var); }
shared.c:
int shared_var = 10;
Cercare di utilizzare hidden_var da un altro file genererà un errore di collegamento.
Cosa succede se si definisce una variabile con lo stesso nome e con diversi specificatori static/extern in moduli diversi?
Risposta: Ogni variabile static (ad esempio, static int foo; in diversi file) è un oggetto completamente indipendente. La dichiarazione extern int foo; cerca una variabile globale condivisa con il nome foo. Non si possono mescolare static ed extern — ciò porterà a un errore di collegamento se in un file foo è definita come static e in un altro è dichiarata extern.
Storia Nel progetto è stata scoperta la duplicazione di funzioni con lo stesso nome (senza static) in diversi moduli: il linker ha collegato solo una di esse, l'altra è "svanita", influenzando la logica dell'applicazione.
Storia In un grande progetto è stata dichiarata una variabile globale
int counter;in due moduli, entrambe le volte senza extern. Di conseguenza, il comportamento dell'applicazione dipendeva dall'ordine di collegamento, talvolta si verificavano simboli conflittuali.
Storia Un modulo usava una funzione con un'errata visibilità: era stata definita come static, e lo sviluppatore cercava di chiamarla da un'altra sorgente — il programma non si compilava senza cambiare il modificatore in extern (o senza rimuovere static).