2015-10-01 6 views
40

Dieser Code kompiliert, aber ich habe Fehler eine Laufzeit in Visual Studio:eine Variable mit dem gleichen Namen in verschiedenen Räumen

Laufzeit 3 ​​# Prüfungsfehler - die Variable ‚x‘ verwendet wird, ohne initialisiert ...

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

ich verstehe nicht, dass das Verhalten ... in dem Fehlerfeld, wenn ich das Programm klicken weiter fortgesetzt und x einen beschädigten Inhalt (wie -8556328 statt 15).

Warum funktioniert dieser Code ohne ein Problem, und das Array int ist gut deklariert?

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

Sie markierten sowohl C und C++. Was hast du kompiliert? –

+3

Einige interessante Fakten: 'gcc 4.8.4', kompiliert und dieses Programm kann mit' -Wall -Wextra -pedantic' ausgeführt werden. 'clang 7.0.0' kompiliert es und kann so ausgeführt werden, wie es ist. Wenn jedoch 'printf ("% d \ n ", x);' nach 'int x = x;' (ich nehme jede tatsächliche Verwendung von 'x') hinzugefügt wird, gibt der Compiler die freundlichere Warnung aus:' warning: variable 'x' ist nicht initialisiert, wenn es innerhalb seiner eigenen Initialisierung [-Wuninitialized] 'verwendet wird. 'gcc' kompiliert und führt es sogar mit dem' printf' und dem Ausdruck '0'. Das Ausführen des Programms durch Valgrind gibt jedoch 'Bedingter Sprung oder Bewegung hängt von nicht initialisierten Wert (en) ' – Joakim

+0

@Joakim: Interessant; Danke für die Ergebnisse.Stehen GCC und Clang innerhalb ihrer Rechte, d. H. Ist das kanonisch undefiniert? –

Antwort

51

x wird links von = definiert.

so in x[x] finden [x] auf den globalen ein,

während in x = x;, x die globalen x versteckt und initialisiert von selbst -> UB.

35

Wenn Sie eine neue Variable zu deklarieren, wird der Name sichtbar hier

int x = 
//  ^- there 

, weil es an diesem Punkt ist die Variable vollständig deklariert wird, und als solche; Der Name bedeutet etwas. Zu diesem Zeitpunkt wird eine andere (zuvor deklarierte Variable) in einem umgebenden Bereich ausgeblendet.

5

Es gibt keinen Bereichsauflösungsoperator in C, so dass Sie möglicherweise nicht

int x = x; 

in Ihrem Programm verwenden können.

+7

Das OP scheint nicht zu wissen, ob sie eine Antwort für C oder C++ möchten. Letzteres unterstützt die Auflösung des Bereichs. –

+0

Ich denke, dass es kompiliert Ich überprüfte es in ideone.com mit dem C-Compiler ... – Aminos

+0

@underscore_d, ja C++ unterstützt und C nicht. – Adi

1

Bitte benutzen Sie SRO (Scope-Auflösung-Operator: :), um Compiler zu sagen, welches x in Ihrem Kopf x ist. Als Benutzer definierten Namen verstümmelt sind (Namen verziert sind) so etwas wie diese Mehrdeutigkeit es Niveau zu vermeiden, sind diese nur durch den Compiler verwendet Namen, die es am besten

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

Auf diese Weise passt wissen Laufzeit, welche Version Sie verwenden, aber um Mehrdeutigkeit zu vermeiden erwartet es von Ihnen, bestimmte Namen zu verwenden. Manchmal tritt oben das Problem auf, wo Sie nicht wissen, dass Sie bereits verwendete Namen verwenden. Dafür hat C++ SRO erstellt.
Jetzt im Fall von Array x Adresse & nicht Ganzzahl, die etwas speichert, deshalb Compiler nicht durcheinander gebracht wurde. Sie müssen schreiben

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; 
} 
Verwandte Themen