Skip to content

Linkage e Visibilità (extern e static)

Quando dividi un programma in più file sorgente (.c), devi capire come il compilatore e il linker collegano insieme funzioni e variabili che hanno lo stesso nome in file diversi. Questo processo è chiamato Linkage (Collegamento).

Il C offre tre tipi di Linkage:

  1. External Linkage (Collegamento esterno)
  2. Internal Linkage (Collegamento interno)
  3. No Linkage (Nessun collegamento, tipico delle variabili locali interne a un blocco)

Quando dichiari una funzione o una variabile globale nel file scope (fuori da qualsiasi funzione) senza modificatori speciali, questa ottiene automaticamente il collegamento esterno. Ciò significa che quella funzione può essere “vista” e richiamata da qualsiasi altro file .c del programma.

Per usare in un file una variabile globale definita in un altro file, si usa la parola chiave extern:

file1.c
int punteggio_globale = 100; // External linkage implicito
file2.c
// Diciamo al compilatore: "Fidati, questa variabile esiste in un altro file!"
extern int punteggio_globale;
void stampa(void) {
printf("%d", punteggio_globale);
}

Un problema comune nell’uso di più file è l’inquinamento del namespace globale (global namespace pollution). Se due file diversi definiscono entrambi una funzione globale o una variabile chiamata init_dati(), il linker andrà in crash per conflitto di nomi (multiple definition error)!

Per evitare questo disastro, usa la parola chiave static applicata a livello di file. Questo assegna alla variabile o alla funzione il collegamento interno, rendendola “invisibile” a tutti gli altri file del programma.

math_util.c
// Questa funzione è visibile solo dentro questo file. È "privata".
static int calcolo_segreto(int x) {
return x * 42;
}
// Questa funzione è pubblica (external linkage) e può essere usata da tutti
int calcola(int x) {
return calcolo_segreto(x) + 1;
}

Nel codice sottostante, simuleremo l’uso di extern in un singolo file. Creeremo uno scenario in cui una funzione fa affidamento su una variabile che dichiara come extern, e la variabile viene definita in un’altra parte. Allo stesso tempo, prova a rendere privata la funzione aiutante con static.