2017-03-01 4 views
2

Ich stehe derzeit vor einem nervigen Problem mit C++.C++ statisches Klassenmitglied nicht initialisiert in einer * statischen Bibliothek *

Eigentlich verstehe ich nicht einmal, warum ich ehrlich nicht für die letzten 20 Jahre :(

In meinem aktuellen Kontext, wir (in Linux Embedded-Systeme meist) verwenden C++ ausführbare Dateien stark statisch unsere eigenen statischen Bibliotheken verknüpft mit. und wir verwenden statische Bibliotheken für die technischen und Optimierungsgründe.

In den letzten Jahren, in der Tat, habe ich allerdings geteilt libs zu schaffen ...

So begann ich zu schreiben einige Klassen mit statischen Klassenmitgliedern wie folgt:

class Inner 
{ 
public: 
    Inner() 
    { 
    std::cout << "CTOR Inner" << std::endl; 
    } 
}; 

class A 
{ 
static Inner _inner; 

... 
}; 

// in the .cpp 

Inner A::_inner; 

/////////////////////// 

Sehr einfacher Anwendungsfall, nicht wahr?

Aber in meinen Unit-Tests, die mit der Lib verbunden sind, kann ich die std::cout Anweisung in der Konsole nicht sehen. Wohingegen, wenn ich meine Klasse Inner und A in den ausführbaren Quellcode verschiebe ... es funktioniert gut.

Ich bin sicher, dass es ein sehr grundlegendes Problem ist und ich realisiere, dass ich in den letzten Jahren nie konfrontiert worden bin. Ist es ein Problem im Zusammenhang mit den Compilern? Bitte beachten Sie, dass ich beide Fälle unter Windows und Linux (Debian, Gcc 4.9) getestet habe.

Jede Idee ist willkommen.

Z.

+0

Globale Variablen sind garantiert nur vor der ersten odr Nutzung eines Unternehmens in seiner enthält Übersetzungseinheit initialisiert werden. Wenn Sie die TU niemals verwenden, ist nicht garantiert, dass Globals initialisiert werden. –

+0

Ok. Also muss ich einen Workaround finden, um ihre Initialisierung "richtig" zu erzwingen ... gut. – Zyend

+0

Was ist der tatsächliche Anwendungsfall davon? Ich finde es ziemlich im Einklang mit der Erwartung, dass die bloße Verbindung zu einer statischen Bibliothek keine Nebenwirkungen hat. Wenn ich etwas nicht verwende, sollte ich nicht dafür bezahlen müssen, das ist ein Designprinzip hinter C und C++. – zett42

Antwort

7

Sie haben zu verwenden, eigentlich ein :: _ inneren irgendwie, dass ein Teil des Codes nicht enthalten sein. Entweder das oder etwas anderes in dieser Datei verwenden. Linker müssen nicht in Übersetzungseinheiten verlinken, die niemals verwendet werden, auch wenn sie beobachtbare Nebenwirkungen haben.

How to force inclusion of "unused" object definitions in a library

+0

Sie ehren Ihren Nick, wirklich! All mein Respekt. –

+0

Danke. Nun ... auf den ersten Blick gibt es keine "saubere" Lösung, um dieses Problem zu beheben. Ich bin kein Fan von #pragma-Anweisungen, da es das ganze Ding so schmutzig wie möglich machen würde ... – Zyend

+0

Ich habe einige Makros definiert, die mir erlaubt haben, "DECLARE_FILE (x)" "DEFINE_FILE (x)" in der Bibliothek header/cpp und dann "USE_FILE (x)" im Hauptprogramm meines Programms. Diese würden einen statischen int erzeugen, der extern und dann im Wesentlichen zugewiesen wäre. Dies führte dazu, dass die Übersetzungseinheit einbezogen wurde und somit die Registrierung stattfand. So etwas erinnert sich sowieso nicht, was ich getan habe. –

Verwandte Themen