Jak líný může být C ++ globální inicializace?

hlasů
9

Jsem zvyklý na myšlení všech inicializace globals / statických třídě-členy as děje před prvním řádku main (). Ale nedávno jsem někde četl, že norma umožňuje inicializace se stane později „pomáhat s dynamickým zatížením modulů.“ Viděl jsem, což je pravda, když dynamické propojení: Já bych nečekal globální inicializaci v knihovně, které mají být inicializovány předtím, než jsem dlopen'ed knihovnu. Nicméně, v rámci seskupení staticky propojeny překladových jednotek (přímé .o soubory mé aplikaci se) Já bych si toto chování velmi unintuitive. Znamená to jen stalo se líně, když dynamicky propojení nebo se může stát kdykoliv? (Nebo to, co jsem si přečetl jen špatně,?)

Položena 06/08/2009 v 15:26
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
6

Norma má následující 3.6.2 / 3:

Je implementace definované zda je či není dynamický inicializační (8.5, 9.4, 12.1, 12.6.1) objektu z rozsahu jmenného prostoru se provádí před prvním prohlášení o main. Je-li inicializace odkládá na nějakém místě v čase po prvním prohlášení o hlavní, musí nastat před prvním použitím jakékoli funkce nebo objekt definován ve stejné jednotce překlad jako objekt, který má být inicializován.

Ale o Samozřejmě můžete nikdy oficiálně říci, kdy inicializace probíhá od inicializace dojde před přístupem k proměnné! jak následuje:

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

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

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

Nemohu odpovídat že g ++ 4.2.4 alespoň jeví provést inicializaci ‚i2‘ před hlavní.

Odpovězeno 06/08/2009 v 15:56
zdroj uživatelem

hlasů
1

Problém, který nikdo nechtěl řešit pomocí tohoto pravidla je jedním z dynamického zatížení. Tento příspěvek se neomezuje na dynamické zatížení a formálně může stát pro jiné případy. Nevím, implementaci, která ji použít pro cokoliv jiného než dynamickým zatížením.

Odpovězeno 06/08/2009 v 15:59
zdroj uživatelem

hlasů
0

Myslím, že to je to, co se stalo v mém případě s g ++ 4.7 a cmake (nejsem si jistý, jestli je to relevantní údaj o cmake). Mám kód, který registruje funkci v továrně. Opírá se o konstruktérovi volajícího z globálně inicializována proměnná.

Když tento kód byl v staticky linkovaná knihovna inicializace se nestalo! To je nyní v pořádku, když jsem se přestěhoval do souborů objektů, které přímo spojených (tj nejsou spojeny do knihovny jako první).

Takže, mám podezření, že máte pravdu.

Odpovězeno 16/09/2013 v 19:31
zdroj uživatelem

hlasů
0

Podívejme se na pseudokódu:

V DLL:

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

V aplikaci:

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

Takže podle statického inicializace AppVar2 dostane 1 + 2 = 3

Lazy inicializace použitelné pro místní statické proměnné (bez ohledu na DLL)

int f()
{
    static int local_i = 5;//it get's 5 only after visiting f()
    return local_i;
}
Odpovězeno 06/08/2009 v 15:48
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more