Perché le variabili globali e statiche vengono inizializzate sui valori predefiniti?

In C / C ++, perché le variabili globali e statiche sono inizializzate su valori predefiniti?

Perché non lasciarlo solo con i valori di spazzatura? Ci sono motivi particolari per questo?

  1. Sicurezza : lasciare la memoria da sola potrebbe perdere informazioni da altri processi o dal kernel.

  2. Efficienza : i valori sono inutili fino a quando non vengono inizializzati su qualcosa, ed è più efficiente azzerarli in un blocco con loop srotolati. Il sistema operativo può persino azzerare le pagine del libero professionista quando il sistema è inattivo, piuttosto che quando alcuni client o utenti sono in attesa dell’inizio del programma.

  3. Riproducibilità : lasciare i valori da soli renderebbe il comportamento del programma non ripetibile, rendendo i bug davvero difficili da trovare.

  4. Eleganza : è più pulito se i programmi possono iniziare da 0 senza dover ingombrare il codice con gli inizializzatori predefiniti.

Ci si potrebbe quindi chiedere perché la class di memorizzazione auto inizi come rifiuti. La risposta è duplice:

  1. In un certo senso, non lo è. La prima pagina del frame dello stack ad ogni livello (cioè ogni nuova pagina aggiunta allo stack) riceve valori zero. I valori “garbage” o “non inizializzati” che le istanze di funzioni successive allo stesso livello di stack vedono sono in realtà i valori precedenti lasciati da altre istanze di metodo del proprio programma e della sua libreria.

  2. Potrebbe esserci una penalità di prestazioni in runtime quadratica (o qualsiasi altra) associata all’inizializzazione di auto (locals di funzioni) su qualsiasi cosa. Una funzione potrebbe non utilizzare uno o tutti gli array di grandi dimensioni, ad esempio, in una determinata chiamata e potrebbe essere invocata migliaia o milioni di volte. L’inizializzazione di statica e globali, OTOH, deve avvenire solo una volta.

Poiché con la corretta cooperazione del sistema operativo, è ansible implementare 0 inizializzando statiche e globali senza sovraccarico di runtime.

Sezione 6.7.8 Inizializzazione dello standard C99 (n1256) risponde a questa domanda:

Se un object con durata di archiviazione automatica non è inizializzato in modo esplicito, il suo valore è indeterminato. Se un object con durata di archiviazione statica non è inizializzato in modo esplicito, allora:

– se ha il tipo di puntatore, viene inizializzato su un puntatore nullo;

– se ha un tipo aritmetico, è inizializzato allo zero (positivo o senza segno);

– se è un aggregato, ogni membro viene inizializzato (in modo ricorsivo) secondo queste regole;

– se si tratta di un sindacato, il primo membro nominato viene inizializzato (in modo ricorsivo) in base a queste regole.

Pensaci, nel regno statico non puoi dire sempre che qualcosa sia effettivamente inizializzato o che il main sia iniziato. C’è anche un init statico e una fase di init dynamic, quella statica prima a destra di quella dynamic in cui l’ordine conta.

Se non avessi azzerato la statica, non saresti assolutamente in grado di dire in questa fase se qualcosa è stato inizializzato a TUTTI e in breve il mondo C ++ andrebbe in pezzi e cose di base come i singleton (o qualsiasi tipo di static static init) avrebbe semplicemente smesso di funzionare.

La risposta con i punti elenco è entusiasta ma un po ‘sciocca. Questi potrebbero tutti applicare all’assegnazione non statica, ma ciò non è fatto (beh, a volte, ma non di solito).

In C, gli oggetti allocati staticamente senza un inizializzatore esplicito vengono inizializzati a zero (per i tipi aritmetici) o un puntatore nullo (per i tipi di puntatore). Le implementazioni di C rappresentano in genere valori zero e valori di puntatore nulli che utilizzano un modello di bit costituito esclusivamente da bit con valore zero (sebbene ciò non sia richiesto dallo standard C). Quindi, la sezione bss in genere include tutte le variabili non inizializzate dichiarate nell’ambito del file (cioè, al di fuori di qualsiasi funzione) e le variabili locali non inizializzate dichiarate con la parola chiave static.

Fonte: Wikipedia