2015-10-01 16 views
40

Questo codice compila, ma ho un errore di tempo di esecuzione in Visual Studio:Utilizzando una variabile con lo stesso nome in diversi spazi

di run-time fallimento di controllo # 3 - la variabile 'x' viene utilizzato senza essere inizializzato ...

int x = 15; 
int main() 
{ 
    int x = x; 
    return 0; 
} 

non capisco che il comportamento ... nella finestra di errore quando si fa clic continuare il programma riprende e x ha un contenuto corrotto (come -8556328 invece di 15).

Perché questo codice funziona senza problemi e l'array int è ben dichiarato?

const int x = 5; 
int main() 
{ 
    int x[x] = {1,2,3,4}; 
    return 0; 
} 
+17

Hai taggato sia C che C++. Quale hai compilato? –

+3

Alcuni fatti interessanti: 'gcc 4.8.4', compila e questo programma può essere eseguito con' -Wall -Wextra -pedantic' acceso. 'clang 7.0.0' lo compila e può essere eseguito così com'è. Tuttavia se 'printf ("% d \ n ", x);' viene aggiunto dopo 'int x = x;' (suppongo che l'uso effettivo di 'x'), il compilatore fornisce l'avviso più amichevole:' warning: variabile 'x' non è inizializzato se usato all'interno della propria inizializzazione [-Wininitialized] '. 'gcc' ancora compila e lo esegue anche con' printf' e stampato '0'. Tuttavia, l'esecuzione del programma tramite valgrind fornisce 'Il salto condizionato o lo spostamento dipende dal/i valore/i non inizializzato/i' – Joakim

+0

@Joakim: Interessante; grazie per i risultatiGCC e Clang sono nei loro diritti, cioè questo comportamento canonicamente indefinito? –

risposta

51

x è definito nella parte sinistra della =.

così in x[x], [x] si riferiscono a quello globale,

mentre in x = x;, x nasconde il globale x e inizializza da sé -> UB.

35

Quando si dichiara una nuova variabile, il suo nome diventa visibile proprio qui

int x = 
//  ^- there 

perché è a quel punto la variabile è completamente dichiarato, e come tale; il suo nome significa qualcosa. A questo punto nel tempo qualsiasi altra (variabile precedentemente dichiarata) in un ambito circostante sarà nascosta.

5

Non v'è alcun operatore di risoluzione dell'ambito in C, in modo da non essere in grado di utilizzare

int x = x; 

nel programma.

+7

L'OP non sembra sapere se vogliono una risposta per C o per C++. Quest'ultimo supporta la risoluzione dell'ambito. –

+0

Penso che compili Ho controllato in ideone.com con il compilatore C ... – Aminos

+0

@underscore_d, sì C++ supporta e C no. – Adi

1

utilizzare SRO (Operatore di risoluzione dell'oscilloscopio: :) per indicare al compilatore quale x è reale x nella propria mente. Come nomi definiti dall'utente sono straziati (I nomi sono decorate) qualcosa di simile per evitare ambiguità al suo livello, questi sono solo nomi usati dalle compilatore che meglio si adatta è

int x = 15;// Real name = gui_x 
int main() 
{ 
    int x = x;// lui_x 
    return 0; 
} 

In questo modo run-time saprà quale versione stai usando ma per evitare ambiguità si aspetta da te di usare nomi specifici. A volte sopra il problema sorge dove non sai che stai usando nomi già usati. Per questo C++ ha creato SRO.
Ora in caso di matrice x è l'indirizzo & non intero che memorizza qualcosa, ecco perché il compilatore non è confuso. Devi scrivere

namespace abc //now all global variables are belongs to this ns abc 
int x = 15;// Real name = gui_x 
int main() 
{ 
int x = abc::x;// lui_x 
return 0; 
}