initialization of cout

S

subramanian100in

I am using g++ 3.4.3 compiler. In this implementation, the header
iostream contains

extern ostream cout;

Since this is only a declaration, I want to know how cout object is
defined/initialized and when is it initialized ? In which file, can I
find the definition of cout(the above being only a declaration) ?

Kindly explain.

Thanks
V.Subramanian
 
M

Michael DOUBEZ

I am using g++ 3.4.3 compiler. In this implementation, the header
iostream contains

extern ostream cout;

Since this is only a declaration, I want to know how cout object is
defined/initialized and ?

cout is an ostream so it is define in the <ostream> header under the
template basic_ostream.

It is initialized in the binary code shipped with your compiler (libc).
when is it initialized ?

Like any other global: at some point before entering main. Now since it
usually depends on the order in which components were linked and since
it is part of standard library, I would expect before the globals of
your program but AFAIK this is not guaranteed.
In which file, can I
find the definition of cout(the above being only a declaration) ?

In <ostream> (or in one of the file included by ostream).
The typedef is defined in <iosfwd>.

With g++3.4.3 it should be:
/usr/include/c++/3.4.3/iostream
/usr/include/c++/3.4.3/iosfwd
 
M

Michael DOUBEZ

Pete said:
cout is an ostream so it is define in the <ostream> header under the
template basic_ostream.

It is initialized in the binary code shipped with your compiler (libc).

and said:
Like any other global: at some point before entering main.

The standard streams (including cout) are different from any other
global. "If a translation unit includes <iostream> or explicitly
constructs an ios_base::Init object, [the standard streams] shall be
constructed before dynamic initialization of non-local objects defined
later in that translation unit." [lib.iostream.objects]/2. And to answer
the complementary question: "The objects are not destroyed during
program execution."

This is the version of the next-to-be-standard (as read from n2798.pdf)
but the current standard states only (27.3/2):

"[...]The objects are constructed, and the associations are established
at some time prior to or during first time an object of class
ios_base::Init is constructed, and in any case before the body of main
begins execution(264). The objects are not destroyed during program
execution.(265)"

From the notes
"264) If it is possible for them to do so, implementations are
encouraged to initialize the objects earlier than required."
"265)Constructors and destructors for static objects can access these
objects to read input from stdin or write output to stdout or
stderr"

Does this mean that it is already guaranteed by the current standard ;
because *Constructors* are included in the note ?
 
J

James Kanze

On 2009-01-13 07:01:05 -0500, Michael DOUBEZ <[email protected]> said:

[...]
The standard streams (including cout) are different from any
other global. "If a translation unit includes <iostream> or
explicitly constructs an ios_base::Init object, [the standard
streams] shall be constructed before dynamic initialization of
non-local objects defined later in that translation unit."
[lib.iostream.objects]/2. And to answer the complementary
question: "The objects are not destroyed during program
execution."

Just a note: you're quoting the CD there, not the current
standard. The current standard doesn't make the guarantee which
results from including <iostream> (but I don't know of an
implementation where including said:
So unless you do something perverse, the standard streams will
have been constructed and not destroyed at any point where you
can see their names.

You mean something as perverse as calling a function defined in
a different translation unit from the constructor of a static
object?

My own policy is that if a translation unit contains objects of
static lifetime with dynamic initialization, I include <ios> and
define a static instance of ios::Init before my objects. (In
the most general case. If the objects are of local types, with
everything in one file, I won't bother.)
 
J

James Kanze

No, I mean writing to a standard stream from a translation
unit that doesn't include <iostream>.

First, I'd consider that a fairly frequent occurance too. Most
of the translation units I have which output don't include
<iostream>, and very little, if any, output occurs in the
translation units where the destination is chosen (which is the
only one which knows that cout exists). However, the scenario I
was thinking of was more on the lines:

unit1.cc:
--------

#include <iostream>

void someFunction()
{
std::cout << "..." ;
}


unit2.cc:
---------

extern void someFunction() ;

class C { C() { someFunction() ; } /* ... */ } ;
C aStaticC ;

There's no guarantee that cout will have been constructed when
C::C calls someFunction.
 
J

James Kanze

On 2009-01-14 17:05:06 -0500, James Kanze <[email protected]> said:

[...]
In practice there is, and in C++0x it's required.

I don't think so (and it's never been guaranteed). The only
thing I find in the CD is "If a translation unit includes
<iostream> or explicitly constructs an ios_base::Init object,
these stream objects shall be constructed before dynamic
initialization of non-local objects defined later in that
translation unit." ([iostream.objects]/2). And in the example
above, the conditions of the if aren't met---unit2.cc doesn't
include <iostream> (since it does no IO), so there's no
guarantee that cout will have been constructed before the
constructor a aStaticC is called.

This isn't new---it was a known problem back in the days of
CFront. CFront more or less masked it by initializing the
translation units in the reverse of the order they were
incorporated into the final executable. Since cout et al. were
in a library which came normally at the end of the link process,
after all user libraries and object files, they would be
initialized first.

FWIW: I just compiled the above with g++ (changing "class" to
struct so that the constructor was accessible, and adding an
empty main()). If I compile with "g++ unit2.cc unit1.cc", no
problem, but "g++ unit1.cc unit2.cc" core dumps before entering
main. Both Sun CC and VC++ work both ways, but historically, I
don't believe it was ever guaranteed---I'm pretty sure I
remember something in the CFront documentation saying that it
wasn't. And unless I'm missing something, it's not guaranteed
even in C++0x.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top