Come vengono inizializzate le variabili locali e globali per impostazione predefinita?

Basato su sotto, ho ragione?

  • Il riferimento globale_A è inizializzato su null.
  • global_int è 0
  • local_A reference è null
  • local_int non è inizializzato
  • Sia global_A.x che local_A.x non sono inizializzati.

Grazie per qualsiasi aiuto.


A global_A; int global_int; class A { public : int x; } int main() { int local_int; A local_A; } 

Accrescere la risposta di Andrey.

$ 3.6.2- “Gli oggetti con durata di memorizzazione statica (3.7.1) devono essere inizializzati a zero (8.5) prima di ogni altra inizializzazione.”. In OP, “global_A” e “global_int” hanno durata di archiviazione statica. “local_int” e “local_A” non hanno alcun collegamento in quanto sono oggetti locali.

$ 8.5 / 5 Per azzerare l’inizializzazione di un object di tipo T significa:

– se T è un tipo scalare (3.9), l’object è impostato sul valore di 0 (zero) convertito in T;

– se T è un tipo di class non di unione, ciascun membro di dati non statici e ciascun sottotabella di class base è zero inizializzato;

– se T è un tipo di unione, il primo membro di dati denominato89 dell’object) viene inizializzato a zero;

– se T è un tipo di matrice, ogni elemento è inizializzato a zero;

– se T è un tipo di riferimento, non viene eseguita alcuna inizializzazione.

$ 6.7.4 / 4- “L’inizializzazione zero (8.5) di tutti gli oggetti locali con durata di memorizzazione statica (3.7.1) viene eseguita prima di ogni altra inizializzazione. Un object locale di tipo POD (3.9) con durata di archiviazione statica inizializzata con le espressioni costanti viene inizializzato prima che il suo blocco venga immesso per primo.Un’implementazione è consentita per eseguire l’inizializzazione anticipata di altri oggetti locali con durata dell’archiviazione statica nelle stesse condizioni in cui è consentita un’implementazione statica di un object con durata dell’archiviazione statica in ambito spazio dei nomi (3.6.2) Altrimenti un object di questo tipo viene inizializzato il primo controllo di tempo passa attraverso la sua dichiarazione, tale object viene considerato inizializzato al completamento della sua inizializzazione.Se l’inizializzazione termina lanciando un’eccezione, l’inizializzazione non è completa, quindi verrà tentato nuovamente la volta successiva che il controllo entra nella dichiarazione Se il controllo rientra nella dichiarazione (in modo ricorsivo) mentre l’object è in fase di iniziale ized, il comportamento non è definito. ”

MODIFICA 2:

$ 8.5 / 9- “Se non è specificato alcun inizializzatore per un object, e l’object è di tipo (non allineato) di tipo non POD (eventualmente qualificato per cv), l’object deve essere inizializzato di default, se l’object è const -qualificato il tipo, il tipo di class sottostante deve avere un costruttore predefinito dichiarato dall’utente , altrimenti, se non è specificato alcun inizializzatore per un object non statico, l’object ei suoi sottooggetti, se presenti, hanno un valore iniziale indeterminato90) , se l’object o qualsiasi dei suoi sottooggetti sono di tipo const-qualificato, il programma è mal formato. ”

In generale, si desidera leggere queste sezioni insieme a $ 8,5 per una buona tenuta su questo aspetto.

Non ci sono riferimenti nel tuo codice, quindi nessuno dei tuoi punti che menzionano “riferimenti” non ha senso.

Nel tuo esempio, entrambi gli oggetti globali – global_int e global_A – sono inizializzati a zero. Entrambi gli oggetti locali – local_int e local_A – contengono valori indeterminati, il che significa che local_int e local_A.x non sono inizializzati.

PS Naturalmente, come già notato, il tuo codice non è compilabile. Non puoi dichiarare oggetti A prima di dichiarare la class A (e ti manca a ; dopo la definizione della class).

Fondamentalmente, ogni volta che si dichiara una variabile, il compilatore chiamerà il suo costruttore predefinito a meno che non si specifichi diversamente.

I tipi di livello di lingua (es. Puntatori, ‘int’, ‘float’, ‘bool’, ecc) “costruttore predefinito” non fa assolutamente nulla, lascia solo la memoria così com’è quando è dichiarata (le variabili globali / statiche sono casi speciali , fare riferimento alla risposta di chubsdad per ulteriori informazioni sulle specifiche). Ciò significa che possono essere praticamente qualsiasi cosa perché di solito non si è sicuri di ciò che era in quella memoria in precedenza o anche da dove proviene la memoria (tranne nel caso dell’operatore ‘placement new’).

La class che hai creato non ha costruttori, quindi il compilatore genererà per te un costruttore predefinito che chiama semplicemente il costruttore di ciascuno dei suoi membri / variabili. Se incorpori le informazioni fornite nel paragrafo precedente, puoi vedere che la variabile ‘x’ avrà il suo costruttore predefinito chiamato, che non fa nulla, e quindi non è inizializzato su alcun valore.

Come altri hanno già detto, non ci sono riferimenti nel codice o nei puntatori, quindi il termine “NULL” non è valido in tutti i casi qui. Normalmente NULL si riferisce a un puntatore che, come altri tipi di livello di lingua, non viene impostato su nulla finché non viene assegnato un valore (a meno che non sia una variabile globale / statica).

Solo per completezza se hai dei riferimenti:

I riferimenti devono essere inizializzati sulla dichiarazione, altrimenti viene punito da un errore del compilatore. Questo significa che un riferimento ha sempre bisogno di un altro valore o riferimento a cui fa riferimento (come dice il), questo è assicurato dal compilatore in modo da non poterlo dimenticare. Ciò implica anche che i riferimenti non possono mai essere puntatori nulli. Tuttavia l’object a cui si riferiscono potrebbe diventare non valido.

global_A e local_A non sono riferimenti; sono oggetti e creati usando i loro costruttori predefiniti. Il costruttore predefinito non è stato specificato, quindi verrà generato, il che non farà nulla, quindi la variabile membro rimarrà non inizializzata.

 A global_A; 

Questa è un’istanza, non un puntatore, il tuo programma chiamerà il costruttore prima di entrare in main.

Per ottenere un puntatore a un’istanza e non un’istanza devi scrivere:

 A* global_A; 

global_int è inizializzato a 0, poiché tutte le variabili globali sono inizializzate ai loro valori predefiniti.

La variabile A local_A verrà inizializzata ogni volta che il programma entra nella funzione in cui è dichiarata da una chiamata al suo costruttore.

Come prima, se vuoi un puntatore a A devi scrivere A * local_A, ma questa volta devi inizializzarlo a NULL tu stesso.

 A *local_A = NULL; 

Il varialle local_int non verrà inizializzato in quanto è un tipo primitivo.

Se local_A.x è inizializzato dipende dal costruttore di A, il costruttore predefinito non inizializzerà local_A.x. Se x dove un’istanza di class che crea un’istanza di A inizializzerà x con il costruttore della sua class.

Tutti richiedono di essere inizializzati. Il compilatore ti avviserà di questo.

Questo codice non verrà compilato se non si inoltra la dichiarazione A.

global_A riferimento è inizializzato su null – No, farà riferimento a un object A. global_int è 0 – Pensa così, devi controllare. local_A reference è nullo – No, come con global_A. local_int non è inizializzato – Sì, otterrà qualche valore inutile. Sia global_A.x che local_A.x non sono inizializzati – Sì.

Puoi sempre eseguire il debug e vedere di persona.

bene ragazzi .. sono più confuso visto che vedo le risposte da qui. Comunque ho fatto un test come mostrato di seguito:

1 # include

  2 using namespace std; 3 4 class A { 5 6 public : 7 A() : x(9) {}; 8 int x; 9 10 }; 11 12 A global_a; 13 int global_b; 14 15 int main() { 16 17 A local_a; 18 int local_b; 19 cout << "global_a.x = " << global_a.x << '\n'; 20 cout << "local_a.x = " << local_a.x << '\n'; 21 22 cout << "global_b = " << global_b << '\n'; 23 cout << "local_b = " << local_b << '\n'; 24 25 } 

Risultati usando il mio compilatore g ++ su ubuntu linux:

global_a.x = 9

local_a.x = 9

global_b = 0

local_b = 0

Penso che local_b dovrebbe essere indefinito, ma in qualche modo il compilatore lo ha inizializzato di default. Comunque local_a .. non sono sicuro se dovrebbe essere inizializzato di default. Dai test qui .. local_a sembrano essere inizializzati. Non sono sicuro che sia conforms alla specifica c ++ standard (es. C ++ PRimer 4th edition dice che il costruttore predefinito viene usato indipendentemente da dove viene dichiarata una variabile di class - vuol dire che la variabile del tipo di class è inizializzata se è globale o locale?).

Qualunque cosa sia .. è un grande inferno di confusione. Forse dovrei smettere di imparare C ++. Java è molto più semplice. Hell yeahhh !!

Il riferimento globale_A è inizializzato su null.

No, è un object valido (costruito in base al costruttore predefinito, che non hai nel tuo codice ma il compilatore aggiunge)

global_int è 0

local_A reference è null

no, lo stesso motivo per il globale

local_int non è inizializzato

no, è inizializzato a 0

Sia global_A.x che local_A.x non sono inizializzati.

no entrambi sono inizializzati a 0