Visibilità e tempo di vita
Visibilità di una variabile
Ambito di azione
Abbiamo visto che, in via del tutto generale, si definisce ambito di azione (o ambito di visibilità o scope) l'insieme di istruzioni di programma comprese fra due parentesi graffe: {....}.
Le istruzioni di una funzione devono essere comprese tutte nello stesso ambito; ciò non esclude che si possano definire più ambiti innestati l'uno dentro l'altro (ovviamente il numero di parentesi chiuse deve bilanciare quello di parentesi aperte, e ogni parentesi chiusa termina l'ambito iniziato con la parentesi aperta più interna).
Variabili locali
In ogni caso una variabile è visibile al programma e utilizzabile solo nello stesso ambito in cui è definita (variabili locali). Se si tenta di utilizzare una variabile in ambiti diversi da quello in cui è definita (o in ambiti superiori in caso di più ambiti innestati), il compilatore non la riconosce.
Il C++ ammette che si ridefinisca più volte la stessa variabile, purché in ambiti diversi; in questo caso riconosce la variabile definita nel proprio ambito o in quello superiore più vicino.
Variabili globali
Una variabile è globale, cioè è visibile in tutto il programma, solo se è definita al di fuori di qualunque ambito (che viene per questo definito: ambito globale). Le definizioni (con eventuali inizializzazioni) sono le uniche istruzioni del linguaggio che possono anche risiedere esternamente all'ambito delle funzioni.
In caso di concorrenza fra una variabile globale e una locale viene riconosciuta la variabile locale; tuttavia la variabile globale prevale se è specificata con prefisso :: (operatore di riferimento globale).
Tempo di vita di una variabile
Variabili automatiche
Una variabile è detta automatica (o dinamica), se cessa di esistere non appena il flusso del programma esce dalla funzione in cui la variabile è definita. Se il flusso del programma torna nella funzione, la variabile viene ricreata ex-novo e, in particolare, viene reinizializzata sempre con lo stesso valore. Tutte le variabili locali sono, per default, automatiche ("tempo di vita" limitato all'esecuzione della funzione).
Variabili statiche
Una variabile è detta statica se il suo "tempo di vita" coincide con l'intera durata del programma: quando il flusso del programma torna nella funzione in cui è definita una variabile statica, ritrova la variabile come l'aveva lasciata (cioè con lo stesso valore); ciò significa in particolare che l'istruzione di definizione (con eventuale annessa inizializzazione) viene eseguita solo la prima volta. Per ottenere che una variabile sia statica, bisogna preporre lo specificatore static nella definizione della variabile.
Esiste anche, per le variabili automatiche, lo specificatore auto, ma è inutile in quanto di default (può essere usato per migliorare la leggibilità del programma).
A differenza dalle variabili automatiche, (in cui, in assenza di inizializzatore, il contenuto iniziale è indefinito), le variabile statiche sono inizializzate di default a zero (in modo appropriato al tipo).
Visibilità globale
Variabili globali statiche
Una variabile locale può essere automatica o statica; una variabile globale è sempre statica (se è visibile dall'esterno deve essere anche viva!) e quindi lo specificatore static non avrebbe significato.
In realtà, nella definizione di una variabile globale, lo specificatore static ha un significato differente: quello di limitare la visibilità della variabile al solo file in cui è definita (file scope). Senza lo specificatore static, la variabile è visibile anche negli altri files, purché in essi venga dichiarata con lo specificatore extern.
Visibilità di variabili globali
Se una variabile globale, visibile in tutti i files sorgente del programma (cioè definita senza lo specificatore static), non é inizializzata, deve esistere una e una sola dichiarazione senza lo specificatore extern, altrimenti il linker darebbe errore, con messaggio "unresolved symbol" (se tutte le dichiarazioni hanno extern), oppure "one or more multiply defined symbols" (se ci sono due dichiarazioni senza extern); se invece la variabile é inizializzata, l'inizializzazione deve essere presente in un solo file (in questo caso lo specificatore extern é opzionale), mentre negli altri files la variabile deve essere dichiarata con extern e non deve essere inizializzata.
Visibilità di costanti globali
In C++ le costanti globali (cioè le variabili globali definite const, con inizializzazione obbligatoria), obbediscono a regole differenti e precisamente:
di default le costanti globali hanno file scope;
affinché una costante globale sia visibile dappertutto, è necessaria la presenza dello specificatore extern anche nella dichiarazione in cui la costante è inizializzata (ovviamente, come per le variabili, l'inizializzazione deve essere presente una sola volta).
Tabella riassuntiva
Visibilità globale |
File scope |
||
specificatore
extern |
specificatore
extern |
||
Variabile globale senza inizializzazione |
vietato |
obbligatorio |
specificatore static |
Variabile globale con inizializzazione |
opzionale |
obbligatorio |
specificatore static |
Costante globale | obbligatorio |
obbligatorio |
default |