Domanda

Voglio sapere perché esattamente statico variabili in C, C ++ e Java vengono inizializzati per zero di default? E perché questo non è vero per le variabili locali?

È stato utile?

Soluzione

Perché le variabili statiche vengono inizializzate in modo deterministico e le variabili locali non sono?

Vedere come le variabili statiche vengono implementati. La memoria per loro è allocata in fase di collegamento, ed il valore iniziale per loro è prevista anche in fase di collegamento. Non v'è alcun overhead runtime.

D'altro canto, la memoria per le variabili locali viene allocato in fase di esecuzione. Lo stack deve crescere. Tu non sai quello che c'era prima. Se si desidera, è possibile cancellare quella memoria (zero), ma che dovrebbe sostenere un overhead runtime. La filosofia C ++ è "non si paga per le cose che non si usa", in modo che non zero, che la memoria di default.

OK, ma perché sono variabili statiche inizializzati a zero, e non qualche altro valore?

Bene, in genere si vuole fare qualcosa con quella variabile. Ma allora come si fa a sapere se è stato inizializzato? È possibile creare una variabile booleana statica. Ma poi ha anche essere inizializzato in modo affidabile a qualcosa (preferibilmente false). Che ne dite di un puntatore? Preferisci lo vogliono inizializzato a NULL di alcuni spazzatura casuale. Che ne dite di una struct / disco? Ha alcuni altri membri di dati all'interno. Ha senso per inizializzare tutti i valori predefiniti. Ma per semplicità, se si utilizza la strategia di "inizializzazione a 0", non c'è bisogno di ispezionare i singoli membri e controllare i loro tipi. Si può solo inizializzare l'intera area di memoria a 0.

Questo non è davvero un requisito tecnico. La semantica di inizializzazione potrebbero ancora essere considerato sano di mente se il valore predefinito è qualcosa di diverso da 0, ma ancora deterministico. Ma allora, che cosa dovrebbe essere tale valore? Si può facilmente spiegare perché viene utilizzato 0 (anche se in effetti suona un po 'arbitraria), ma spiegando -1 o 1024 sembra essere ancora più difficile (in particolare che la variabile non può essere abbastanza grande da contenere il valore, ecc).

E si può sempre inizializzare la variabile in modo esplicito.

E si ha sempre il paragrafo 8.5.6 della serie C ++ che dice "Ogni oggetto della durata di stoccaggio statico deve essere zero inizializzata all'avvio del programma".

Per ulteriori informazioni, si prega di fare riferimento a queste altre domande:

Altri suggerimenti

Paragrafo 8.5.6 del C ++ norma stabilisce che:

"Ogni oggetto della durata di conservazione statica deve essere zero inizializzata all'avvio del programma"

(La norma dice anche che l'inizializzazione delle variabili locali non è definito)

Per quanto riguarda il motivo per cui, la norma non lo dice;.) Una delle ipotesi è che è abbastanza facile da implementare, senza svantaggi aggiuntivi

Parlando per Java:

le variabili locali devono essere inizializzate prima di poter accedere, perché si tratta di un guadagno di sicurezza. I controlli del compilatore per voi, se la variabile è sicuramente impostato.

le variabili statiche o di classe (con un tipo di oggetto) vengono inizializzati con null, perché il compilatore non può controllare se vengono inizializzati al momento della compilazione. Invece di lasciare che il programma di fallire se si accede a una variabile non inizializzata, verrà inizializzato implicita con null.

Le variabili con un tipo nativo non possono ottenere un valore null, quindi le variabili non-locali vengono inizializzati con 0 o false, come ripiego. Non è la soluzione migliore, certo, ma non so uno migliore. ; -)

Quindi, in una certa misura queste sono solo progettare decisioni da parte dei progettisti di linguaggi. Ma le ragioni probabili per queste decisioni in Java sono:

  • per le variabili statiche / membro, se avete intenzione di loro inizializzare a qualcosa, allora lo zero è un valore conveniente perché (a) è generalmente un valore adatto a significare "non impostato a qualsiasi altra cosa di speciale", ed è il valore avresti scelto comunque in alcuni casi, come ad esempio contatori; e (b) internamente, è probabile che zero può essere impiegato per valori "speciali", in particolare per rappresentare nullo nel caso di un riferimento all'oggetto.
  • per le variabili locali, dando loro alcun valore predefinito consente la regola che obbliga il programmatore per impostare un valore prima di leggere la variabile, che in realtà può essere utile nel permettere al compilatore di individuare alcuni errori.

Nel caso di variabili locali, è anche ipotizzabile che una variabile locale può essere dichiarato (che a livello di codice / macchina bytecode essenzialmente mezzi allocare spazio dello stack / spostando il puntatore stack) ma poi non effettivamente scritto / letto in un particolare percorso di codice. Quindi, non avendo un valore predefinito evita di fare il lavoro necessario di impostazione di un default in questi casi.

Ripeto, però, si tratta di decisioni di progettazione in una certa misura. Sono essenzialmente un compromesso tra ciò che è probabile che sia conveniente per implementazioni di JVM e conveniente per i programmatori.

NB. In C / C ++, le variabili "statiche" significa una cosa diversa a variabili statiche in Java!

Non ho idea su Java e dubito che sia diverso per statica / locali in Java.

Per quanto riguarda la C e C ++, si tratta di prendersi cura di programmatori il loro effetto di codice e amorevole essere in controllo. L'inizializzazione delle variabili locali implicherebbe l'esecuzione di codice in più ogni programma a tempo entra nel campo di applicazione. Per chiamati più frequentemente funzioni che possono essere un disastro.

Questo ha a che fare con il concetto di "pagare solo per quello che si utilizza" in C / C ++.

Per variabili statiche, un'inizializzazione può essere fatta senza generare codice. Il file oggetto contiene i valori iniziali per le variabili nel segmento dei dati e quando il sistema operativo carica i carichi IT eseguibili e mappe questo segmento di dati prima che il programma inizia l'esecuzione.

Per le variabili locali non c'è modo per inizializzare loro senza il codice, perché non vengono inizializzati una volta, dovrebbero essere inizializzati ogni volta che si entra la portata; anche essi sono allocati nello stack, e quando l'allocazione si verifica il valore iniziale dello stack nel caso generale è semplicemente quello che c'era prima (ad eccezione di quei rari momenti si cresce lo stack più che si è sviluppato in precedenza).

Quindi, per inizializzare implicitamente una variabile locale il compilatore avrebbe bisogno di generare il codice senza il programmatore comanda esplicitamente di farlo, che è abbastanza contro quella "filosofia".

A proposito di Java, per quanto ne so, le variabili sono sempre inizializzate quando il programma entra nel loro campo di applicazione, non importa se essi sono statici o no. L'unica differenza significativa tra loro è che l'ambito di variabili statiche è l'intero programma. Dato che, il comportamento è coerente tra tutti loro.

Questa è solo una supposizione, ma potrebbe essere il modo in cui lo è per la statica dal momento che è facile da implementare, e utile.

Il compilatore può co-allocare tutte le variabili in un'area di memoria contigui, e quindi sia emettere codice (una singola chiamata memset()) per cancellare prima main() è chiamato. In molti casi può anche contare su caratteristiche del formato di file eseguibile del sistema operativo, se questo formato supporta " bss sezioni ", che viene controllata dal caricatore invece. Ciò consente di risparmiare spazio nel file eseguibile, si potrebbe avere

static unsigned char megabyte[1 << 20];

e l'eseguibile non sarebbe cresciuto da un megabyte.

Per le variabili locali, nessuno di questi si applicano; essi sono allocati "on the fly" (in genere su una pila) e sarebbe uno spreco di risorse per cancellare loro, dato che sono in genere sta per essere assegnato a molto presto comunque.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top