2013-03-29 9 views
16

Clang warnt (bei Verwendung von -Weverything oder Wglobal-constructors) über Konstruktoren für statische Objekte.Wie mit Global-Konstruktor Warnung in Clang umgehen?

warning: declaration requires a global constructor 
     [-Wglobal-constructors] 
A A::my_A; // triggers said warning 
    ^~~~ 

Warum ist das relevant und wie soll man mit dieser Warnung umgehen?

Einfaches Beispiel Code:

class A { 
    // ... 
    static A my_A; 
    A(); 
}; 

A A::my_A; // triggers said warning 
+2

auf CR_DEFINE_STATIC_LOCAL basieren können wir die Warnung sehen, bitte? – jrok

+0

ist dies in einer .h-Datei? – yngccc

+0

Sie haben ein Objekt von A innerhalb der Klasse A. Wie funktioniert das? Wird dies rekursiv - auch wenn das Objekt statisch ist? Obwohl es nur einen my_A gibt und die Rekursivität keine Probleme verursacht, kann ich immer noch 'A;; & dann .mY_A.my_A.my_A.my_A usw. – user93353

Antwort

16

Hier ist ein einfacher Fall, der die gleiche Warnung auslöst:

class A { 
public: 
    // ... 
    A(); 
}; 

A my_A; // triggers said warning 


test.cpp:7:3: warning: declaration requires a global constructor [-Wglobal-constructors] 
A my_A; // triggers said warning 
    ^~~~ 
1 warning generated. 

Das ist völlig legal und sicher C++.

Aber für jeden nicht-trivialen globalen Konstruktor, den Sie haben, leidet die Startzeit Ihrer Anwendung. Die Warnung ist lediglich eine Möglichkeit, Sie über dieses potenzielle Leistungsproblem zu informieren.

Sie können die Warnung mit -Wno-global-Konstruktoren deaktivieren. Oder Sie können zu einem verzögerten Initialisierungsschema wie folgt wechseln:

A& 
my_A() 
{ 
    static A a; 
    return a; 
} 

das vermeidet das Problem vollständig (und unterdrückt die Warnung).

+10

Sind Sie sicher, dass die Leistung das Hauptproblem ist? Ich würde denken, dass ein größeres Problem auftreten könnte - da die Ordnung der globalen/statischen Initialisierung in C++ undefiniert ist, könnte nicht-triviales globales Objekt in seinem Konstruktor eine Abhängigkeit von einem anderen globalen Objekt einführen, was zu undefiniertem Verhalten führt. – SomeWittyUsername

+0

okay danke. Ich glaube, ich war verwirrt von der Formulierung * globaler Konstruktor *. Vielleicht wäre etwas wie * Konstruktion beim Start * passender. – Walter

+0

@icepack guter Punkt. Dies kann tatsächlich in meinem Code auftreten, obwohl ich noch nie ein Problem festgestellt habe ... – Walter

3

Lösung von @Howard Hinnant vermeiden globalen Konstruktor, aber es verlassen Zeit Destruktor noch. Es kann mit der Option -Wexit-time-destructors

So Ideale Lösung gefunden werden kann von http://src.chromium.org/svn/trunk/src/base/basictypes.h

A& my_A() 
{ 
    static A &a = *new A; 
    return a; 
} 
+2

Dieser Code erstellt Warnungen von Speicherverlust-Tools. –

+1

natürlich! Destruktor wird für diesen Code nicht aufgerufen. – Speakus

+0

@DavidFaure Konnte der Speicherleck nicht vermieden werden, indem man eine 'static unique_ptr ' (anstelle von 'static A &') in 'A :: my_A()' hält? – Walter

Verwandte Themen