C ++: Wann (und wie) heißen die C ++ Global Static Constructors?
Arbeite ich auf einige C++ - code, und ich habe laufen in eine Frage, die wurde nörgelnden mich für eine Weile... Vorausgesetzt, ich kompiliere mit GCC auf einem Linux host für ein ELF den Gegner, wo sind Globale statische Konstruktoren und Destruktoren aufgerufen?
Ich habe gehört es gibt eine Funktion _init in crtbegin.o, und eine Funktion _fini in crtend.o. Sind diese aufgerufen, indem crt0.o? Oder wird der dynamische linker eigentlich erkennen, Ihre Präsenz in der geladenen binären und Sie nennen? Wenn dem so ist, wenn sieht es eigentlich nennen?
Bin ich hauptsächlich daran interessiert zu wissen, so kann ich verstehen, was hinter den kulissen geschieht, wie mein code geladen wird, ausgeführt, und dann entladen zur Laufzeit.
Vielen Dank im Voraus!
Update: ich bin im Grunde versucht, um herauszufinden, die Allgemeine Zeit, zu der die Konstruktoren aufgerufen werden. Ich möchte nicht, dass Annahmen in meinem code basierend auf diesen Informationen ist es mehr oder weniger um ein besseres Verständnis von dem, was passiert auf den unteren Ebenen, wenn mein Programm geladen. Ich verstehe, das ist ziemlich OS-spezifisch, aber ich habe versucht einzugrenzen, ein wenig in dieser Frage.
InformationsquelleAutor der Frage Matthew Iselin | 2009-08-13
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn man über nicht-lokale statische Objekte gibt es nicht viele Garantien. Wie Sie bereits wissen (und es wurde auch hier erwähnt), sollte es keinen code schreiben, hängt davon ab. Die static initialization order fiasco...
Statischen Objekten geht, die durch ein zwei-Phasen-Initialisierung: statische Initialisierung und dynamische Initialisierung. Der ehemalige geschieht zunächst und führt die null-Initialisierung oder die Initialisierung von Konstanten Ausdrücken. Letzteres geschieht, nachdem alle statischen Initialisierung gemacht wird. Dies ist, wenn die Konstruktoren aufgerufen werden, zum Beispiel.
Im Allgemeinen, so wird diese Initialisierung geschieht in einer Zeit, bevor main(). Jedoch, im Gegensatz zu dem was viele Leute denken auch das ist nicht garantiert der C++ - standard. Was ist in der Tat gewährleistet wird, dass die Initialisierung abgeschlossen ist, bevor die Verwendung jeder Funktion oder ein Objekt definiert in der gleichen übersetzungseinheit als das Objekt wird initialisiert. Beachten Sie, dass dies nicht OS-spezifisch. Diese ist C++ - Regeln. Hier ein Zitat von der Standard:
InformationsquelleAutor der Antwort Leandro T. C. Melo
Dies hängt stark auf den compiler und die Laufzeit. Es ist nicht eine gute Idee, machen Sie keine Annahmen über die Zeit, die Globale Objekte konstruiert werden.
Dies ist insbesondere ein problem, wenn man ein statisches Objekt, das hängt davon ab, daß die andere schon aufgebaut.
Dies wird als "static initialization order fiasco". Auch wenn das nicht der Fall in Ihrem code, die C++Lite FAQ-Artikel zu diesem Thema sind es Wert, gelesen zu werden.
InformationsquelleAutor der Antwort ebo
Dies ist nicht OS-spezifisch, eher seine compiler-spezifisch.
Haben Sie die Antwort gegeben, die Initialisierung erfolgt in
__init
.Für den zweiten Teil, in gcc sicherzustellen, können Sie die Reihenfolge der Initialisierung mit einem
____attribute____((init_priority(PRIORITY)))
befestigt, um eine variable definition, woPRIORITY
einige relative-value -, mit niedrigeren zahlen erst initialisiert.InformationsquelleAutor der Antwort Gunther Piez
Den Empfänger haben Sie:
Wenn Sie Annahmen, dass Abhängigkeiten voneinander haben Sie zwei Möglichkeiten:
Beispiel 1: Global Ein Konstruktor verwendet Globale log -
Beispiel Globale B-Destruktor verwendet, der Globalen log -
Hier haben Sie grantee, dass die log-Objekt nicht zerstört wird, bevor das Objekt B. Dies bedeutet, dass Anmeldung muss vollständig aufgebaut, bevor B (als umgekehrter Reihenfolge der Zerstörung, wird die Regel dann anwenden). Wieder die gleichen Techniken können verwendet werden. Legen Sie Sie in der gleichen übersetzungseinheit oder eine Funktion um log.
InformationsquelleAutor der Antwort Martin York
Entsprechend der C++ - standard, den Sie aufgerufen werden, bevor irgendeine Funktion oder ein Objekt Ihrer übersetzungseinheit verwendet wird. Beachten Sie, dass für die Objekte im globalen namespace dies würde bedeuten, Sie sind initialisiert, bevor
main()
genannt wird. (Siehe ltcmelo ist und Martin Antworten, für mehr details und eine Diskussion zu diesem.)InformationsquelleAutor der Antwort sbi