Die Lebensdauer von Funktionsvariablen static
beginnt beim ersten Auftreten [0] des Programmflusses auf die Deklaration und endet beim Beenden des Programms. Dies bedeutet, dass die Laufzeit eine Buchführung durchführen muss, um sie nur dann zu zerstören, wenn sie tatsächlich erstellt wurde.
Da der Standard besagt, dass die Destruktoren statischer Objekte in umgekehrter Reihenfolge nach Abschluss ihrer Konstruktion ausgeführt werden müssen [1] und die Reihenfolge der Konstruktion von der spezifischen Programmausführung abhängen kann, muss außerdem die Reihenfolge der Konstruktion berücksichtigt werden .
Beispiel
struct emitter {
string str;
emitter(const string& s) : str(s) { cout << "Created " << str << endl; }
~emitter() { cout << "Destroyed " << str << endl; }
};
void foo(bool skip_first)
{
if (!skip_first)
static emitter a("in if");
static emitter b("in foo");
}
int main(int argc, char*[])
{
foo(argc != 2);
if (argc == 3)
foo(false);
}
Ausgabe:
C:> sample.exe
Erstellt in foo
Zerstört in foo
C:> sample.exe 1
Erstellt in if
Erstellt in foo
Zerstört in foo
Zerstört in if
C:> sample.exe 1 2
Erstellt in foo
Erstellt in wenn
zerstört in wenn
zerstört in foo
[0]
Da C ++ 98 [2] keinen Verweis auf mehrere Threads hat, ist das Verhalten in einer Umgebung mit mehreren Threads nicht spezifiziert und kann problematisch sein, wie Roddy erwähnt.
[1]
Abschnitt C ++ 98 3.6.3.1
[basic.start.term]
[2]
In C ++ 11 werden Statiken threadsicher initialisiert. Dies wird auch als Magic Statics bezeichnet .
[basic.start.term]
Motti hat Recht mit der Bestellung, aber es gibt noch einige andere Dinge zu beachten:
Compiler verwenden normalerweise eine versteckte Flag-Variable, um anzuzeigen, ob die lokale Statik bereits initialisiert wurde, und dieses Flag wird bei jedem Eintrag in die Funktion aktiviert. Natürlich ist dies ein kleiner Leistungseinbruch, aber was noch besorgniserregender ist, dass dieses Flag nicht garantiert threadsicher ist.
Wenn Sie eine lokale Statik wie oben haben und
foo
von mehreren Threads aufgerufen werden, können Race-Bedingungen auftreten, die dazu führenplonk
, dass sie falsch oder sogar mehrmals initialisiert werden. Auch in diesem Fallplonk
kann es durch einen anderen Thread als den, der ihn erstellt hat, zerstört werden.Ungeachtet dessen, was der Standard sagt, wäre ich sehr vorsichtig mit der tatsächlichen Reihenfolge der lokalen statischen Zerstörung, da es möglich ist, dass Sie sich unabsichtlich darauf verlassen, dass eine Statik nach ihrer Zerstörung noch gültig ist, und dies ist wirklich schwer zu finden.
quelle
Die vorhandenen Erklärungen sind ohne die eigentliche Regel aus dem Standard in 6.7 nicht wirklich vollständig:
quelle
FWIW, Codegear C ++ Builder zerstört nicht in der erwarteten Reihenfolge gemäß dem Standard.
... was ein weiterer Grund ist, sich nicht auf den Zerstörungsbefehl zu verlassen!
quelle
Die statischen Variablen werden nach Beginn der Programmausführung ins Spiel gebracht und bleiben verfügbar, bis die Programmausführung endet.
Die statischen Variablen werden im Datensegment des Speichers erstellt .
quelle