Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it guaranteed by the C++ standard that cin, cout, etc. will be created first and destroyed last?

Tags:

c++

c++11

stl

cin, cout, basic streams related - is it guaranteed anywhere in the standard that these obejcts will be created first and destroyed last?

It would implicate that non-local static objects can rely on them in their constructors and destructors (no ctor race between these objects and the basic streams).

like image 462
hauron Avatar asked Nov 21 '14 11:11

hauron


2 Answers

They are guaranteed to be created before any static object declared after including <iostream> and, in any case, before starting main. They are not destroyed during program execution.

Including the header has the effect of declaring a static variable of type ios_base::Init, whose creation ensures that the standard streams are initialised.

If you want the Standardese for this:

C++11 27.4.1 [iostream.objects.overview]/2: The objects are constructed and the associations are established at some time prior to or during the first time an object of class ios_base::Init is constructed, and in any case before the body of main begins execution. The objects are not destroyed during program execution. The results of including <iostream> in a translation unit shall be as if <iostream> defined an instance of ios_base::Init with static storage duration. Similarly, the entire program shall behave as if there were at least one instance of ios_base::Init with static storage duration.

like image 198
Mike Seymour Avatar answered Sep 23 '22 02:09

Mike Seymour


The simple answer to your question is no. As others have pointed out, there are guarantees for objects defined in translation units including <iostream>, at least if the object is defined after the inclusion. But this doesn't always help: you include <iostream> in the translation unit which defines the constructor, not necessarily in the one which defines the static variable. So cases like the following are possible:

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;

In this case, it's quite possible that the constructor of anX be called before std::cout is constructed.

To be on the safe side: if the constructor of an object which might be used as a static variable wants to use any of the standard streams, it should probably declare a local static of type ios_base::Init:

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

If std::cout wasn't already constructed when this constructor is called, it will be when the static variable is constructed.

like image 30
James Kanze Avatar answered Sep 23 '22 02:09

James Kanze