Globale Initialisierungsreihenfolge in C: Abhängigkeiten ignorieren
In C ist die Initialisierungsreihenfolge globaler Variablen innerhalb einer Übersetzungseinheit genau definiert. Allerdings können Abhängigkeiten zwischen Globals ignoriert werden, was zu überraschendem Verhalten führt.
Beachten Sie den folgenden Code:
<code class="cpp">struct Foo; extern Foo globalFoo; struct Foo { Foo() { printf("Foo::Foo()\n"); } void add() { printf("Foo::add()\n"); } static int addToGlobal() { printf("Foo::addToGlobal() START\n"); globalFoo.add(); printf("Foo::addToGlobal() END\n"); return 0; } }; Foo globalFoo; int dummy = Foo::addToGlobal(); int main() { printf("main()\n"); return 0; }</code>
Beim Kompilieren mit GCC 4.4.3 lautet die erwartete Ausgabe:
Foo::Foo() Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END main()
Dies liegt daran, dass die globale Variable globalFoo vor dem Aufruf der statischen Methode Foo::addToGlobal() initialisiert wird. Wenn wir jedoch die Reihenfolge von globalFoo und Dummy-Deklaration vertauschen, wird die Ausgabe wie folgt:
Foo::addToGlobal() START Foo::add() Foo::addToGlobal() END Foo::Foo() main()
Es scheint, dass die Instanzmethoden von Foo für eine nicht erstellte Instanz aufgerufen werden. Dies liegt daran, dass die Reihenfolge der globalen Initialisierung Abhängigkeiten ignoriert.
Um sicherzustellen, dass der Konstruktor von Foo vor der Initialisierung von Dummy aufgerufen wird, müssen wir sicherstellen, dass globalFoo vor Dummy in derselben Übersetzungseinheit definiert wird. Alternativ können wir einen statischen Zeiger auf die globale Instanz verwenden, der vor jeder dynamischen Initialisierung auf Null initialisiert wird. Die addToGlobal-Methode kann dann prüfen, ob der Zeiger null ist, und bei Bedarf das globale Foo erstellen.
Das obige ist der detaillierte Inhalt vonWarum führt der Austausch globaler Variablendeklarationen in C zu unerwartetem Verhalten?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!