Topic: Defect report, [iostreams.objects], [ios::Init: no requirement that standard streams be flushed


Author: James Kanze <james.kanze@gmail.com>
Date: Thu, 14 May 2009 13:13:35 CST
Raw View
As currently formulated, the standard doesn't require that there
is ever a flush of cout, etc.  (This implies, for example, that
the classical hello, world program may have no output.)  In the
current draft (N2798), there is a requirement that the objects
be constructed before main, and before the dynamic
initialization of any non-local objects defined after the
inclusion of <iostream> in the same translation unit.  The only
requirement that I can find concerning flushing, however, is in
[ios::Init], where the destructor of the last
std::ios_base::Init object flushes.  But there is, as far as I
can see, no guarantee that such an object ever exists.

Also, the wording in [iostreams.objects] says that: "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."  In [ios::Init], however, as an
effect of the constructor, it says that "If init_cnt is zero,
the function stores the value one in init_cnt, then constructs
and initializes the objects cin, cout, cerr, clog
wcin, wcout, wcerr, and wclog", which seems to forbid earlier
construction.

Suggested changes:

[iostream.objects]/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 lifetime.
     Similarly, the entire program shall behave as if there
     were at least one instance of ios_base::Init with static
     lifetime.

[ios::Init]/3:
     Effects: Constructs an object of class Init.  Constructs
     and initializes the objects cin, cout, cerr, clog, wcin,
     wcout, wcerr and wclog if they have not already been
     constructed and initialized.

[ios::Init]/4:
     Effects: Destroys an object of class Init.  If there are
     no other instances of the class still in existance,
     calls cout.flush(), cerr.flush(), clog.flush(),
     wcout.flush(), wcerr.flush(), wclog.flush().

(Note that with these changes, the exposition only "static
int init_cnt" in ios_base::Init can be dropped.)

Of course, a determined programmer can still inhibit the
flush with things like:
     new std::ios_base::Init ;       //  never deleted
or (in a function):
     std::ios_base::Init ensureConstruction ;
     //  ...
     exit( EXIT_SUCCESS ) ;

Perhaps some words somewhere to the effect that all
std::ios_base::Init objects should have static lifetime
would be in order.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                    Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


--
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@netlab.cs.rpi.edu]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]