2014-11-21 11 views
6

cin, cout, podstawowe strumienie powiązane - czy jest zagwarantowane w dowolnym miejscu standardu, że te obiekty zostaną utworzone jako pierwsze i zniszczone jako ostatnie?Czy to gwarantuje standard C++, że cin, cout itp. Zostaną stworzone jako pierwsze i zniszczone jako ostatnie?

Sugerowałoby to, że nielokalne obiekty statyczne mogą polegać na nich w swoich konstruktorach i destruktorach (bez wyścigu ctor pomiędzy tymi obiektami a podstawowymi strumieniami).

Odpowiedz

7

Gwarantuje się, że zostaną utworzone przed zadeklarowanym statycznym obiektem, w tym <iostream>, aw każdym razie przed rozpoczęciem main. Nie są niszczone podczas wykonywania programu.

Włączenie nagłówka powoduje zadeklarowanie zmiennej statycznej typu ios_base::Init, której utworzenie zapewnia zainicjowanie standardowych strumieni.

Jeśli chcesz Standardese dla tego:

C++ 11 27.4.1 [iostream.objects.overview]/2: obiekty są zbudowane i stowarzyszenia są ustalone w pewnym momencie przed lub po raz pierwszy skonstruowany jest obiekt klasy ios_base::Init, a w każdym razie zanim ciało główne rozpocznie wykonywanie. Obiekty nie są niszczone podczas wykonywania programu. Wyniki włączenia <iostream> w jednostce tłumaczeniowej powinny być takie, jak gdyby <iostream> zdefiniował wystąpienie ios_base::Init z czasem przechowywania statycznego. Podobnie, cały program powinien zachowywać się tak, jakby istniało co najmniej jedno wystąpienie o wartości ios_base::Init z czasem przechowywania statycznego.

+0

'main' nie jest jedyną rzeczą, którą napisałby programista. Globały i statyka również są kandydatami. – Ajay

+0

@Ajay: Rzeczywiście, dlatego 'main' nie jest jedyną rzeczą, o której wspomniałem. Jak już powiedziałem, strumienie są gwarantowane, że zostaną utworzone przed zadeklarowanym statycznym obiektem, włączając w to ''. –

+0

Nie mówię, że jesteś w błędzie Mike, ale wątpię. Dlaczego: Mogę mieć wiele nagłówków, zawartych we właściwej kolejności (lub nie). Nie ma gwarancji, że pierwsze nagłówki zostaną umieszczone w fazie inicjacji łącznika/modułu ładującego w danej sekwencji. A może jest gwarancja? Jeśli nie, włączenie '' jest niczym innym jak włączeniem tekstu. Tak, mam świadomość, że rzeczywisty kod klasy strumienia znajduje się w bibliotece uruchomieniowej (DLL, SO lub static-lib). Jeśli tak, to czy obiekty DLL/SO/LIB zostaną najpierw zainicjowane? I znowu, jaka jest gwarancja tego zamówienia? – Ajay

7

Prosta odpowiedź na twoje pytanie brzmi: nie. Jak inni wskazali, gwarancje dla obiektów zdefiniowanych w jednostkach translacjizapewniają obiekty zdefiniowane w jednostkach translacyjnych , w tym <iostream>, co najmniej, jeśli obiekt jest zdefiniowany po włączeniu do obiektu. Ale to nie zawsze pomaga: dodajesz <iostream> w jednostce tłumaczeniowej, która definiuje konstruktora, niekoniecznie w tym, który definiuje zmienną statyczną. Możliwe są przypadki, tak jak na poniższym :

file1.hh

class X 
{ 
public: 
    X(); 
}; 

file1.cc

#include "file1.hh" 
#include <iostream> 

X::X() 
{ 
    std::cout << "Coucou, me voila!" << std::endl; 
} 

file2.cc

#include "file1.hh" 

X anX; 

W tym przypadku, jest to całkiem możliwe, że konstruktor anX zostanie wywołany przed std::cout jest zbudowany.

Aby być na bezpiecznej stronie: jeśli konstruktor obiektu, który może być używany jako zmienna statyczna chce wykorzystać dowolny ze standardowych strumieni, to prawdopodobnie powinien zadeklarować lokalne statyczne typu ios_base::Init:

X::X() 
{ 
    static ios_base::Init dummyForInitialization; 
    std::cout << "Coucou, me voila!" << std::endl; 
} 

Jeśli std::cout nie został jeszcze skonstruowany, gdy wywoływany jest ten konstruktor , będzie to oznaczać, gdy zostanie zbudowana zmienna statyczna.

+0

Dziękujemy za użyteczny przykład "udawanie", że jest to cout/cin safe :) – hauron

+0

** + 1 ** za kontrprzykład. –

+0

Ta odpowiedź z praktycznego punktu widzenia jest bardziej przydatna - pokazuje przykład i sposób rozwiązania problemu. Pytanie zadano o standard, ale uważam, że odpowiedzi razem tworzą "idealną odpowiedź", dlatego wybrałem odpowiedź Mike'a i głosowałem za tym. – hauron

Powiązane problemy