1

In what cases and why is this necessary:

class ios_base::Init {
    static int init_cnt;  // internal static counter (for exposition only)
public:
    Init();
    ~Init();
}

Have it from this site: cpluplus.com - ios_base::init

I read the description and meditated about it, but this did not help much...

8
  • The internal counter? For keeping track of how many objects were created, for one. Could be used as an overly simple way of generating unique object ids. Commented Dec 30, 2013 at 12:19
  • Thanks for the answer, but that is not my question. On the page I linked it says: "This class is an instantiation of basic_ios designed to serve as base class for all wide stream classes, with wchar_t as character type (see basic_ios for more info on the template)." I do not understand what this actually means...
    – Michael
    Commented Dec 30, 2013 at 12:21
  • 3
    Are you asking why the Init class exists at all? From your link - so that standard stream objects "are constructed and properly initialized." Why does that matter? Cos globals are evil.
    – doctorlove
    Commented Dec 30, 2013 at 12:21
  • But are they not automatically constructed when I do something like "cout << "test" << endl;" - I guess I misunderstand something fundamentally.
    – Michael
    Commented Dec 30, 2013 at 12:23
  • 1
    @Michael, for you to call operator<< on cout, its must already be a valid object. Which means it must have been previously constructed. Commented Dec 30, 2013 at 12:27

2 Answers 2

1

It's a workaround for the static initialization order fiasco. Essentially, if you want to use the global stream objects from a static initializer, you can call this to ensure that they're all constructed in time. Runtimes I'm familiar with already do this properly, but technically speaking that's not guaranteed.

(Note also that as of C++11, it is guaranteed.)

2
  • 1
    The implementation of the standard library and supporting utilities. The iostreams library is part of the runtime library.
    – Sneftel
    Commented Dec 30, 2013 at 12:33
  • What is guaranteed in C++11? As far as I can see, the guarantees are exactly the same as they've been since CFront (pre C++98). And which runtimes guarantee that the global stream objects are always constructed first. (I'm pretty sure that g++ doesn't, since it's crt0 is in C, not in C++.) Commented Dec 30, 2013 at 12:46
1

They're needed to ensure the correct initialization of the standard iostream objects, like std::cout. Basically, the standard iostream objects are guaranteed to be constructed by the time the first constructor of ios_base::Init has finished. (The init_cnt member is part of one technique of achieving this.) In addition, the standard says that including <iostream> declares a static instance of ios_base::Init (or behaves as if it does), so if you write:

#include <iostream>

class X
{
public:
    X() { std::cout << "something";
};
X anXwithStaticLifetime;

you're guaranteed that std::cout will be constructed before the constructor of anXwithStaticLifetime is run.

Of course, this only works within a single translation unit. If you define in a header ("X.hh"):

class X
{
public:
    X();
};

and then in two different translation units:

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

X::X()
{
    std::cout << "something";
}

and:

#include "X.hh"
X anXwithStaticLifetime;

it's quite possible that std::cout will not have been constructed when you execute the constructor. The usual way of ensuring this is to define a local instance of ios_base::Init in the constructor:

X::X()
{
    static ios_base::Init toEnsureInitialization;
    std::cout << "something";
}

In practice, most implementations use additional tricks to reduce the risk. But as far as I know, none of them are 100%, and depending on how you link, you can still get into problems. But they won't occur if you do things the usual way. With the results that a lot of programmers aren't aware of the risk, and don't make the necessary declaration (and it almost always works anyway).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.