La variabile globale e statica di inizializzazione a 0 non è sempre necessaria?

Lo standard C garantisce che le variabili globali e statiche, se non inizializzate, sono sempre 0 .

Ecco la mia domanda: le variabili globali e statiche non inizializzate vanno al segmento BSS nel programma. Quindi il cosiddetto 0 dovrebbe essere all-bit 0 .

Per le variabili integrali, all-bit 0 verrà valutato come 0 . Le variabili in virgola mobile, se seguono IEEE 754 , sono anch’esse 0.0 . Ma per i puntatori, i puntatori nulli non devono necessariamente essere all-bit 0 , quindi l’inizializzazione di un puntatore globale come questo:

 int* p = NULL; 

fare la differenza solo per:

 int *p; 

Lo standard garantisce che un puntatore con durata dell’archiviazione statica e nessun altro inizializzatore verranno inizializzati per essere un puntatore nullo, indipendentemente da quale modello di bit possa coinvolgere.

La stessa idea di base si applica anche ai tipi in virgola mobile e interi: sono garantiti per essere inizializzati su 0 o 0.0. L’implementazione può lasciare questo al fatto che BSS imposta tutti i bit su 0 se e solo se “sa” che così facendo si otterranno i valori corretti.

Tutte le variabili con durata di memorizzazione statica sono garantite per essere inizializzate ai rispettivi valori zero, il che generalmente non significa che debbano essere fisicamente riempiti con un modello a zero bit.

La ragione per cui tali variabili potrebbero andare nel segmento BSS su una piattaforma specifica è che sulla piattaforma di destinazione il puntatore nullo è effettivamente rappresentato da un modello tutto-bit-zero. Cioè l’inizializzazione a zero bit per i puntatori funziona correttamente su quella piattaforma, quindi il compilatore utilizza BSS come il modo più semplice ed efficace per implementare il comportamento corretto su quella piattaforma specifica. Se così non fosse, il compilatore dovrebbe inizializzare tali variabili statiche in modo diverso.

Ciò si applicherebbe ai valori a virgola mobile, ad esempio, se alcune piattaforms usassero una rappresentazione non IEEE 754 per tali valori con un modello di bit diverso da zero per rappresentare 0.0 (C non impone IEEE 754).

(Inoltre, questo si applicava anche a tutti i tipi interi maggiori di char , fino a quando uno dei TC per lo standard C99 richiedeva infine che il modello all-bit-zero fosse una rappresentazione object valida per zeri interi di tutti i tipi su tutte le piattaforms C.)

Un buon esempio di vita reale viene dal C ++ (una lingua diversa ma rilevante in questo caso). C ++ offre la stessa garanzia per le variabili scalari con durata di archiviazione statica. Nel frattempo, molte popolari implementazioni in C ++ usano il valore 0xFFFFFFFF per rappresentare i puntatori nulli del tipo di membro puntatore-dati. Per esempio

 SomeType SomeClass::*p = 0; 

in realtà si traduce in codice che riempie p di pattern tutto-bit-uno. Quindi, se si dichiara una variabile statica di tale tipo senza un inizializzatore esplicito, il compilatore dovrà assicurarsi che il suo valore iniziale sia tutto-bit-un modello, non tutto-bit-zero. Alcuni compilatori sono noti per sbagliare inserendo tali variabili in BSS che si dimenticano di esse, lasciando quindi tali variabili piene di pattern tutto-bit-zero.