Ich verstehe nicht, was das folgende Codebeispiel tut und wie sie es tut:C++ globale Variable Initialisierungsreihenfolge
#include <stdio.h>
int f();
int a = f(); // a exists just to call f
int x = 22;
int f() {
++x;
return 123; // unimportant arbitrary number
}
int main() {
printf("%d\n", x);
}
Wenn dies es 23
lief druckt, was die intuitive Antwort.
In C++ sind jedoch globale Variablen supposed to be in der Reihenfolge der Definition initialisiert. Das würde bedeuten, dass a
vor x
initialisiert werden sollte, weil es vor x
definiert ist. Wenn dies der Fall wäre, müsste die Funktion f
aufgerufen werden, bevor x
initialisiert wurde, da der Aufruf an f
ein Teil der Definition a
ist.
Wenn f
ist in der Tat aufgerufen, bevor x
initialisiert wird, würde das bedeuten, dass f
würde versuchen x
zu erhöhen - das Ergebnis von denen ich bin nicht wirklich sicher (höchstwahrscheinlich UB, oder einem Kauderwelsch-Wert). Nachdem a
initialisiert wurde, wird x
auf 22
initialisiert und das Programm würde 22
ausdrucken.
Offensichtlich passiert das nicht, was passiert. Aber was ist? Was macht der Code eigentlich?
Es scheint definitiv wie x
-22
vor a = f()
gesetzt wird ausgewertet, aber das würde bedeuten, dass die Reihenfolge der Initialisierung umgekehrt wird (ich könnte auch falsch sein, was die Initialisierung ist, oder wenn es passiert).
So im Wesentlichen wird die Initialisierung in den nicht-Seite bewirkende Teil getrennt, dass „runs“ erster (keine Funktionen, Code nur Baugruppe, die den Speicher verändert und inkrementiert den Stapelzeiger) und einen Nebeneffektteil, der als zweiter läuft (in dem die tatsächlichen Funktionen ausgeführt werden). Und wenn eine Funktion nachweislich keine Nebenwirkungen hat, kann sie in den ersten Teil gehievt werden. Verstehe ich es richtig? Es macht Sinn. Außerdem hast du 'x = f();' geschrieben, aber ich denke, du meintest 'a = f(); '(das steht in meinem Code). – corazza
Auch der erste Satz Ihres letzten Absatzes ist ein wenig seltsam: * Wenn dieses Hochziehen passiert, ist es zulässig, dass die resultierenden Anfangswerte anders sein können als wenn es nicht passiert wäre. * - was meinst du? Es sieht irgendwie so aus, als hättest du ein "es" verpasst, aber im Allgemeinen ist das, was du beschreibst, ein bisschen verwirrend, vielleicht würde das Posten dieses Beispiels helfen? – corazza
@yannbane: Das Beispiel ist in dem Abschnitt, den ich zitiert habe. Ich zögere, große Teile davon zu kopieren, weil Sie im Wesentlichen alles lesen sollten. Ich empfehle dir [gehe zu github] (https://github.com/cplusplus/draft) und schnappe dir eine Kopie des Standards. Ja, es gibt zwei Phasen. Die erste Phase verändert nicht einmal den Speicher - die Anfangswerte werden einfach in die Binärdatei geschrieben und vom Loader in den Speicher geladen. –