Warum kann ich zwei statische Klassenvariablen in einer einzelnen Datei in der falschen Reihenfolge initialisieren, aber nicht in drei?

8

Ich habe mit statischen Klassenvariablen herumgespielt und bin auf etwas Unerwartetes gestoßen, das ich nicht verstehe.

Stroutrups Buch TC ++ PL4 sagt in 15.4.1 Initialisierung nichtlokaler Variablen: "Es gibt keine garantierte Reihenfolge der Initialisierung von globalen Variablen in verschiedenen Übersetzungseinheiten." Aber sehen Sie das für mehrere Übersetzungseinheiten; Ich habe keine Abhängigkeiten zwischen Dateien getestet, dies war in einer einzigen Datei. Derselbe Abschnitt sagt "Im Prinzip wird eine Variable, die außerhalb jeder Funktion definiert ist (dh globale Variablen, Namespaces und statische Klassenvariablen), initialisiert, bevor main() aufgerufen wird. Solche nicht lokalen Variablen in einer Übersetzungseinheit werden in ihrer Definitionsreihenfolge initialisiert.

Wenn ich dies am Anfang der Datei eingerichtet habe:

%Vor%

Ich kann das tun:

%Vor%

Und diese Anweisung in main setzen, um die Werte zu überprüfen:

%Vor%

Und beide Werte werden 1,125 sein. Ich verstehe, dass beide Variablen an diesem Punkt definiert werden müssen, aber wenn sie in der Reihenfolge der Definition initialisiert werden, wie kommt es dann, dass eine obige Aussage die Daten aus einer unten stehenden Aussage verwendet? Auch die Reihenfolge der Klassendefinitionen oben ändert nichts in diesen Fällen.

Wenn ich diese Anordnung verwende:

%Vor%

Sie werden auch alle 1.125 sein.

Aber wenn ich das tue:

%Vor%

Test3::test3 wird 0 sein.

Es sieht so aus, als könnte es nach einer anderen Definition für eine Ebene suchen, aber wenn diese Definition eine andere Definition benötigt, wird sie gestoppt und nur mit Null versehen. Aber ich weiß nicht, was wirklich passiert.

Weiß jemand, warum es das tut? Ich habe dies im C ++ '14-Modus von Ссылка (GCC) und in VSE 2012 mit konsistenten Ergebnissen versucht.

EDIT: Sehen Sie, ich sehe überall, dass Sie es nicht vorhersagen können, aber diese Beobachtung scheint die scheinbare Tatsache zu übertünchen, dass es einen Unterschied zwischen der Unsicherheit zwischen Dateien und der (möglicherweise nicht vorhandenen?) Unsicherheit innerhalb einer einzigen Datei gibt . Stroustrup sagte im Grunde, dass es einen Unterschied gibt, aber statische Variablen sind seltsam.

Ich hatte gedacht, dass es möglich ist, dass eine Klassendefinition außerhalb der ursprünglichen Datei aussieht, um das statische Datenelement selbst bei einer einzelnen Datei zu initialisieren, so dass die Datei im Hinblick auf die Kompilierungslogik sich wiederholt, um sich selbst wiederzufinden. UB erzeugen. Wenn ein Compiler programmiert würde, um Null zuzuweisen, anstatt zu einer dritten externen Variablen zu springen, wäre das Ergebnis vorhersagbar und stabiler, aber ich habe keinen Beweis, dass eine Datei sich so extern referenzieren kann.

EDIT 2: Es scheint eine Frage der statischen und dynamischen Initialisierung zu sein, wobei die statische Initialisierung zur Kompilierungszeit null oder eine gegebene Konstante zuweist und die dynamische dann diese Werte verwendet (wie Mark B sagte): Was ist die dynamische Initialisierung von Objekten in C ++? Aber ich muss fragen, ob es UB ist oder nicht, immer noch.

LAST EDIT: Es war nicht schwer Informationen zu finden, das Verhalten ist sehr gut fundiert und nicht UB, siehe hier: Ссылка

    
Lunarian 01.11.2015, 21:57
quelle

1 Antwort

5

Was also hier passiert ist, dass es zwei Phasen der Initialisierung gibt: statisch und dynamisch. Der Compiler kann sehen, dass test1 eine Konstante ist und diese Konstante in die Binärdatei einbettet, standardmäßig wird sie auf den Wert gesetzt. Dies kann nicht für test2 und test3 geschehen, also erhalten diese Werte von 0 in der Binärdatei.

Dann, bevor main startet, beginnt die dynamische Initialisierungsphase, setzt den Wert 0 von test2 in test3 und dann die Konstante 1.25 von test1 in test2 .

Alles, was nie gesagt hat, verlässt sich darauf und initialisiert Ihre Variablen immer in einer vernünftigen Reihenfolge.

    
Mark B 01.11.2015, 22:33
quelle

Tags und Links