2010-07-13 29 views
21
#include <stdio.h> 
int main() { 
    int c = c; 
    printf("c is %i\n", c); 
    return 0; 
} 

Sto definendo una variabile intera denominata c e sto assegnando il suo valore a se stesso. Ma come può anche questo essere compilato? c non è stato inizializzato, quindi come può essere assegnato il suo valore a se stesso? Quando eseguo il programma, ottengo c is 0.Perché questo codice C viene compilato?

Suppongo che il compilatore stia generando codice assembly che assegna lo spazio per la variabile c (quando il compilatore rileva l'istruzione int c). Quindi prende qualsiasi valore indesiderato in quello spazio non inizializzato e lo assegna a c. E 'questo che sta succedendo?

+3

Sfortunatamente, è permesso - si può normalmente fare in modo che il compilatore emetta un avvertimento su di esso, per esempio usando g ++ (ma non gcc per qualche motivo) usando il flag -Wall genera un avvertimento. –

+7

@Neil, per forzare un errore con gcc, si usa '-Werror = non inizializzato -Winit-self' –

risposta

30

Mi ricordo di aver citato questo in una risposta precedente ma non riesco a trovarlo al momento.

C++ 03 §3.3.1/1:

Il punto di dichiarazione per un nome è subito dopo la sua completa dichiaratore (clausola 8) e prima della sua inizializzazione (se presente), ...

Pertanto la variabile c è utilizzabile anche prima della parte di inizializzatore.

Modifica: Mi dispiace, hai chiesto informazioni su C in particolare; anche se sono sicuro che ci sia una linea equivalente. James McNellis trovato:

C99 §6.2.1/7: "ha portata che inizia subito dopo il completamento del suo dichiaratore" Ogni identificatore che non è una struttura, unione, o tag di enumerazione Il dichiaratore è seguito dall'inizializzatore.

+0

Spot on! '+ 1' ....... –

+0

Grazie! Ottima spiegazione! –

+12

C99 §6.2.1/7: Qualsiasi identificatore che non è una struttura, unione o tag di enumerazione "ha uno scope che inizia subito dopo il completamento del suo dichiaratore." Il dichiaratore è seguito dall'inizializzatore. –

2

c è stato inizializzato!

Anche se questa è una riga di codice, in realtà sta inizializzando c, quindi assegnandogli c. Sei solo fortunato che il compilatore sta inizializzando c a zero per te.

+0

-1 ...errato e sbagliato, ma ancora votato più alto ... la variabile 'c' nell'esempio mostrato non è un puntatore, ma è allocata in pila. – gnud

+4

Cosa? Chi ha detto che doveva essere un puntatore? –

+1

Non sono d'accordo - 'c' non è inizializzato per me (a seconda delle opzioni del compilatore), evidenziato da un output diverso da zero quando si esegue questo codice. – pilcrow

5

È comportamento indefinito di utilizzare un valore non inizializzato (§C99 J.2 "Il valore di un oggetto con durata di memorizzazione automatica viene utilizzato mentre è indeterminato"). Quindi tutto può succedere da nasal demons a c = 0, a playing Nethack.

+0

Il valore è indeterminato, ma non è un comportamento non definito. Demoni nasali e Nethack sono fuori. c = 0 è possibile (e probabile). Il comportamento qui è definito in modo simile a un generatore di numeri casuali in quanto, sebbene non possiamo determinare il valore risultante, possiamo essere garantiti dallo standard che il valore è l'unica cosa sconosciuta a questa affermazione. –

11

La tua ipotesi è giusta. int c spinge lo spazio nello stack per la variabile, che viene quindi letta e riscritta per la parte c = c (sebbene il compilatore possa ottimizzarlo). Il tuo compilatore sta premendo il valore come 0, ma non è sempre garantito.

+0

+1 Ben spiegato. –

+4

Probabilmente non sta spingendo 0, è solo che il frame dello stack esistente contiene già 0 memoria. A seconda che ci sia 0, ovviamente non è definito. –

+0

+1 molto utile! –

2

Le specifiche C non garantiscono che le variabili vengano inizializzate su 0, 0.0 né su "" o "".

Questa è una funzionalità di compilatori e non è mai necessario che ciò accada.

Ho sempre impostato il mio IDE/compilatore per avvertirlo.

Problemi correlati