Wenn Sie die Initialisierung von cMyConstDouble2
dazu ändern:
const double cMyConstDouble2 = 2.5*3.14;
Dann sollten Sie Ihr Programm korrekt verhalten. Der Grund dafür ist, dass Variablen, die
- Have POD Typ
- mit konstanten Ausdrücken initialisiert (1)
bei statischer Initialisierung initialisiert werden. Diese Initialisierungen umfassen
- Null Initialisierung von alle Objekte statischen Lagerdauer
- Initialisierungen von PODs initialisiert mit konstanten Ausdrücken
Ihrer gezeigten Variablen mit nur cMyConstDouble
erfüllt beide Bedingungen werden vollständig initialisiert zur statischen Initialisierungszeit. cMyConstDouble2
tut dies jedoch nicht, da sein Initialisierer die Anforderungen eines konstanten Ausdrucks nicht erfüllt.Insbesondere enthält es eine Variable, die keinen Integraltyp hat (hier hat sie Gleitkommatyp). Fließkomma Literalesind zulässig in arithmetischen Konstantenausdrücken. Deshalb ist 2.5*3.14
ein arithmetischer Konstantenausdruck. Aus diesem Grund muss der Initialisierer geändert werden, damit er statisch initialisiert wird.
Was mit cMyConstDouble2
passieren wird, wenn Sie mit dem nicht konstanten Ausdruck bleiben? Die Antwort ist, du weißt es nicht. Der Standard ermöglicht, dass diese Variable statisch initialisiert wird, erfordert dies jedoch nicht. In Ihrem Fall wurde es dynamisch initialisiert - somit war sein Wert gleich nach der statischen Initialisierungszeit immer noch Null. Um ein Gefühl dafür, wie komplizierten zu erhalten, die, hier ist ein Beispiel:
inline double fd() { return 1.0; }
extern double d1;
double d2 = d1; // unspecified:
// may be statically initialized to 0.0 or
// dynamically initialized to 1.0
double d1 = fd(); // may be initialized statically to 1.0
Wenn die dynamische Initialisierung ändert sich nicht, andere statische Speichergröße (in zufrieden Ihren Code) und wenn die statischen Initialisierung würde den gleichen Wert erzeugen, der bei dynamischer Initialisierung erzeugt würde, wenn alle Objekte, die nicht statisch initialisiert werden müssen, dynamisch initialisiert werden (auch erfüllt in Ihr Code) - dann darf die Variable statisch initialisiert werden. Diese beiden Bedingungen sind auch zufrieden in den obigen Code für beide Variablen d2
und d1
:
Analyse von d2
= d1
keine andere statische Speichervariable
- ändern Wenn beide
d2
und d1
dynamisch initialisiert , dann würde d2
zu 0.0
initialisiert werden, weil d2
vor d1
definiert ist, und dynamische Initialisierung von d2
wäre gr. ab dem Wert d1
ab dem Zustand unmittelbar nach der statischen Initialisierung (wo nur Null Initialisierung von d1
stattfand).
Analyse von d1
= fd()
keine andere statische Speicher
- Variable ändern Wenn beide
d2
und d1
dynamisch initialisiert werden, dann wird = fd()
d1
-1.0
initialisieren.
So kann der Compiler d1
statisch 1.0
, initialisiert werden, da beide Bedingungen für optionale statisch-Initialisierung erfüllt sind.
Wenn der Compiler entscheidet d1
und d2
dynamisch zu initialisieren, dann d2
wird 0.0
initialisiert werden, da sie den Wert von d1
greifen, wie es kurz nach Null Initialisierung war.
jedoch, wenn entscheidet der Compiler d1
statisch und d2
dynamisch zu initialisieren, dann d2
wird 1.0
, initialisiert werden, da die dynamische Initialisierung der d2
den vollständig initialisierte Wert von d1
greifen, wie es war kurz nach der statischen Initialisierung.
Ich bin mir nicht sicher, was der Wert von d2
ist, wenn d1
undd2
statisch initialisiert werden, though. Das heißt, ob d2
die 0.0
oder 1.0
greifen soll, da keine Reihenfolge für die statische Initialisierung definiert ist.
(1) Konstante Ausdrücke umfassen arithmetischen konstanten Ausdrücke auch (nicht nur ganzzahlige konstante Ausdrücke), wenn die Initialisierung Reihenfolge von Objekten mit statischer Speicherdauer berücksichtigen.
@Suma: Wenn das 'cMyConstDouble2' nicht konstant gefaltet ist, weil' cMyConstDouble' 'extern' ist, sollte das nicht auch bei' cAnotherDouble' passieren? Das hängt auch von 'cMyConstDouble' oder? Wie kommt es ist Wert richtig gedruckt als 3.454 – legends2k
Reihenfolge der Initialisierung über Module ist undefiniert. In einem Fall war es schon gemacht, in der zweiten nicht. – Suma