2012-12-04 28 views
10

Wiem, że zmienne globalne są tworzone w kolejności deklaracji dla tej samej jednostki kompilacji, a kolejność tworzenia nie jest zdefiniowana między wieloma jednostkami kompilacji.Gdy statyczna zmienna globalna jest tworzona w C++

Czytałem jakiś czas temu, że zmienne globalne są tworzone przed wywołaniem dowolnego kodu z jednostki kompilacji, w której są zdefiniowane. Czy jest to określone przez normę?

przykład:

file1.cpp

int f1v1 = f1_1(); 
int f1v2 = f1_2(); 

void f1(){...} 

int f1_1(){...} 
int f1_2(){...} 

file2.cpp

static int f2v1 = f2_1(); 
static int f2v2 = f2_2(); 

int f2_1(){...} 
int f2_2(){...} 

main.cpp

#include "file1.h" 
#include "file2.h" 

int main() 
{ 
    f1(); 

    return 0; 
} 

w tym przypadku jest gwarantowana przez normy, które f1_1() jest wywoływane przed f1_2() i przed f1()? Gwarantuje standard, że f2_1() i f2_2() są wywoływane, ponieważ żadna funkcja zdefiniowana w pliku file2.cpp nie jest wywoływana, a f2v1 i f2v2 są niewidoczne poza plikiem file2.cpp?

EDIT:

Czy zachowanie określone przez normę gdy file1.cpp jest skompilowany w LIB1 i file2.cpp jest skompilowany w LIB2?

+0

Możesz znaleźć ten http://stackoverflow.com/questions/12321401/ dynamiczna inicjalizacja użyteczne – hmjd

+0

Uwaga: czy "statyczny" lub tylko efekt * powiązania * zmiennej, jej inicjalizacja jest identyczna. –

+0

@ MatthieuM. Chciałem wyjaśnić, że zmienne nie są używane (dostęp z innego miejsca) – Felics

Odpowiedz

4

podstawie [basic.start.init]:

f1_1() gwarantowana jest do wykonania przed f1_2() (para.2: „Zmienne z zamówionej inicjalizacji określonej w ramach jednej jednostki tłumaczeniowej zostaje zainicjowany w kolejności ich definicje w jednostce tłumaczeniowej. ").

Oba są gwarantowane do wykonania przed f1() (para.4: „Jeśli jest odroczone do inicjalizacji pewnym momencie po pierwszym zestawieniu głównym, musi nastąpić przed pierwszym ODR użycia (3.2) z dowolnej funkcji lub zmienna zdefiniowana w tej samej jednostce tłumaczeniowej, co zmienna do zainicjowania. ").

O f2_1() i f2_2() [basic.stc.static] para.2 mówi „Jeśli zmienna ze statycznym okres przechowywania ma inicjalizacji lub destruktor z efektów ubocznych, nie powinny być wyeliminowane nawet jeśli wydaje się być nieużywany, ... ". Oznacza to, że mają gwarancję, że zostaną wezwani, jeśli będą zawierać skutki uboczne.

0

Jeśli mam zrozumieć swoje właściwe pytanie, C++ gwarantuje kolejność inicjalizacji zmiennych według kolejności deklaracji obrębie jednej jednostki kompilacji (czyli plików CPP). Kolejność inicjowania w różnych jednostkach kompilacji jest niezdefiniowana.

W procesie kompilacji, gdy f2_* funkcje zgodnie z normą byłoby nazwać, choć funkcjonuje w file2.cpp nie prowadził. Ale jeśli kompilator jest wystarczająco inteligentny, można go całkowicie pominąć, jeśli ustali, że wynikowy program będzie działał tak, jakby był zgodny ze standardem. (to znaczy.jeśli może zagwarantować poza cieniem wątpliwości, że nie byłoby różnicy w zachowaniu między programem a programem bez wywoływania tych funkcji)