Frage

Ich bin zum Denken aller Initialisierung von Globals / statisch-Klasse-Mitgliedern wie geschieht vor der ersten Zeile der main () verwendet. Aber ich habe irgendwo gelesen, vor kurzem, dass die Standard-Initialisierung später passieren können zu „hilft bei der dynamischen Belastung von Modulen.“ Ich könnte diese wahr, wenn eine dynamische Verbindung sehen: Ich würde nicht eine globale in einer Bibliothek initialisiert erwarten initialisiert werden, bevor ich die Bibliothek dlopen'ed. Doch innerhalb einer Gruppierung von statisch gelinkte zusammen Übersetzungseinheiten (meine App direkt .o Dateien) Ich würde dieses Verhalten sehr unintuitive finden. Ist dies nur träge passieren, wenn dynamisch verknüpfen oder es kann jederzeit passieren? (Oder war das, was ich gerade falsch gelesen;)

War es hilfreich?

Lösung

Der Standard wird folgend in 3.6.2 / 3:

  

Es ist die Implementierung definiert, ob die dynamische Initialisierung (8.5, 9.4, 12.1, 12.6.1) eines Objekts   Namespacebereich ist vor der ersten Anweisung des Haupt getan. Wenn die Initialisierung bis zu einem gewissen Punkt aufgeschoben   in der Zeit nach der ersten Mitteilung der Haupt, wird sie vor der ersten Benutzung von einem beliebigen Funktion oder Objekt auftritt definiert   in derselben Übersetzungseinheit als das Objekt initialisiert werden.

Aber o Natürlich können Sie nie offiziell sagen, wenn die Initialisierung stattfindet , da die Initialisierung auftritt, bevor Sie auf die Variable zugreifen! als folgt:

// t1.cc
#include <iostream>
int i1 = 0;

int main () {
  std::cout << i1 << std::endl

// t2.cc
extern int i1;
int i2 = ++i1;

Ich kann anpassen, dass g ++ 4.2.4 mindestens erscheint die Initialisierung von ‚i2‘ vor dem Haupt auszuführen.

Andere Tipps

Das Problem, dass man mit dieser Regel lösen wollte, ist das eines der dynamischen Belastung. Die Zulage ist nicht auf dynamische Belastung begrenzt und formal für andere Fälle passieren könnte. Ich weiß nicht, eine Implementierung, die es sonst als dynamische Belastung für alles verwendet werden.

Lassen Sie uns einen Pseudo-Code überprüfen:

In DLL:

static int ItsDllVar = 1;
int EXPORTED_FUNCTION() { return ItsDllVar; }

Anwendung:

static int AppVar1 = 2;
static int AppVar2 = EXPORTED_FUNCTION() + AppVar1;

So nach statischer Initialisierung AppVar2 erhält 1 + 2 = 3

Verzögerte Initialisierung anwendbar für lokale statische Variablen (unabhängig von DLL)

int f()
{
    static int local_i = 5;//it get's 5 only after visiting f()
    return local_i;
}

Ich denke, das ist das, was in meinem Fall mit g passierte ++ 4.7 und CMake (nicht sicher, ob dies ein relevantes Detail in Bezug auf CMake ist). Ich habe einen Code, der eine Funktion in der Fabrik registriert. Es stützt sich auf dem Konstruktor von einem global initialisiert Variable aufrufen.

Wenn dieser Code war in der statisch gelinkte Bibliothek die Initialisierung ist nicht geschehen! Es ist jetzt gut funktioniert, wenn ich es auf die Objektdateien verschoben, die direkt verbunden (das heißt, sie sind nicht in eine Bibliothek kombiniert zuerst).

Also, ich vermute, dass Sie richtig sind.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top