I forgot to add this important information: you don't get the nifty counters if you don't include <iostream>. Specifically. That means including <istream> or <ostream> does not introduce any nifty counter. Including <ssteam>, which allows you to perform in-memory formatted IO, does not introduce any nifty counter. Said, differently, the worry about IOStreams introducing unnecessary "static constructor" is either overblown or misplaced, or both.
-- Gaby On Wed, Nov 21, 2012 at 8:25 AM, Gabriel Dos Reis <g...@integrable-solutions.net> wrote: > On Wed, Nov 21, 2012 at 7:48 AM, Tobias Grosser <tob...@grosser.es> wrote: > >> Is it correct to state that every translation unit that includes iostream >> will include the iostream static constructors? > > C++ requires the definitions of globals such as std::cin, std::cout, > and std::cerr > that must be contructed (by any magic) before users attempt to use them. To > aid > with this, the C++ standard formalizes the programming pattern known as > `nifty counter' in the form of the class std::ios_base::Init such that > (quoting C++) > > The class Init describes an object whose construction ensures the > construction of the eight objects declared in <iostream> (27.4) > that associate > file stream buffers with the standard C streams provided for by the > functions declared in <cstdio> (27.9.2). > > Whether a compiler decides to implement this with "static constructor" is > an implementation detail issue. Of course, since no object is constructed > more than once, no actual iostream object constructor is run more than > once. You can see how we implemented this in libstdc++ > > > http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/src/c%2B%2B98/ios_init.cc?revision=184997&view=markup > >> Will the number of static >> constructors increase linearly with the number of translation units? Is it >> necessary to include iostream in a core header, in case we want to use >> iostream for the debugging functionality? > > I think this is the case or premature optimization and you are worrying > about the wrong thing. Every translation unit that includes <iostream> > gets a static global variable of an empty class type (therefore occupying > 1 byte). See > > > http://gcc.gnu.org/viewcvs/trunk/libstdc%2B%2B-v3/include/std/iostream?revision=184997&view=markup > > That 1 byte triggers a *dynamic* intialization from the corresponding > translation unit. However, the actual iostream objects are constructed > only once. > >> >> >>> e of it. Only the translation that includes >>> iostream gets the niftty counters. >>> >>> Furthermore, not including iostream does not mean you don't >>> get static constructors -- GCC has lot of global variables and if >>> any of them incures dynamic initialization, you get >>> dynamic initialization. Note also that if you explicitly delay >>> initialization to runtime, you are going to pay for it anyway >>> through brittle manual initialization. >> >> >> I was mainly interested in compering FILE* and iostream. To my knowledge the >> FILE* interface does not have any significant construction overhead. > > You are kidding me, right? > > Anyway, I think you are focusing on the wrong thing. > For GCC's homegrown IO occurs far more overhead than > you appear to believe - I am saying this from my work on the > diagnostic machinery; we can do a better job if we had > a more typed interface. This is true not only for the > diagnostic machinery, which is partly used by the various > debug systems, but also of the debug systems themselves. > You are worrying about something I suspect you would not be able to > measure compared to the performance of the existing > debug systems. > > -- Gaby