P0W P0W - 1 month ago 5
C++ Question

Use of static data inside iostream header

I was playing around on godbolt.org, and noticed some "extra code" added by compiler with an 'empty main()' with

iostream
header included.

After looking into standards I figured those are needed to constructs and initializes the objects
cin
,
cout
,
cerr
,
clog
,
wcin
,
wcout
,
wcerr
, and
wclog,
if they have not already been constructed/initialized.

N4606: § 27.5.3.1.6


27.5.3.1.6 Class ios_base::Init [ios::Init]

namespace std {
class ios_base::Init {
public:
Init();
~Init();
private:
static int init_cnt; // exposition only
};
}



But for the
static
data all that standard says it counts the number of constructor and destructor calls for
class Init
, and is initialized to zero.


2 For the sake of exposition, the maintained data is presented here
as: (2.1) — static int init_cnt, counts the number of constructor and
destructor calls for class Init, initialized to zero.


What I don't get is what is the use of
static int init_cnt;
here ?
Why we need to counting how many times constructor/destructor is called ?

Answer

Based on https://github.com/maniacbug/StandardCplusplus/blob/master/ios.cpp#L163 I think that if is needed then program at the end when calling destructors for global variables can properly destruct cin, cout, cerr, clog, wcin, wcout, wcerr and wclog.

From http://www.csci.csusb.edu/dick/c++std/september/lib-iostreams.html :

~Init();

Effects: Destroys an object of class Init. The function subtracts one from the value stored in init_cnt and, if the resulting stored value is one, calls cout.flush(), cerr.flush(), clog.flush(), wcout.flush(), wcerr.flush(), wclog.flush().