Section: 31.5.4.3 [basic.ios.members] Status: C++11 Submitter: Martin Sebor Opened: 2008-05-17 Last modified: 2016-01-28
Priority: Not Prioritized
View all other issues in [basic.ios.members].
View all issues with C++11 status.
Discussion:
The fix for issue 581, now integrated into the working paper, overlooks a couple of minor problems.
First, being an unformatted function once again, flush()
is required to create a sentry object whose constructor must, among
other things, flush the tied stream. When two streams are tied
together, either directly or through another intermediate stream
object, flushing one will also cause a call to flush()
on
the other tied stream(s) and vice versa, ad infinitum. The program
below demonstrates the problem.
Second, as Bo Persson notes in his
comp.lang.c++.moderated post,
for streams with the unitbuf
flag set such
as std::stderr
, the destructor of the sentry object will
again call flush()
. This seems to create an infinite
recursion for std::cerr << std::flush;
#include <iostream> int main () { std::cout.tie (&std::cerr); std::cerr.tie (&std::cout); std::cout << "cout\n"; std::cerr << "cerr\n"; }
[ Batavia (2009-05): ]
We agree with the proposed resolution. Move to Review.
[ 2009-05-26 Daniel adds: ]
I think that the most recently suggested change in [ostream::sentry] need some further word-smithing. As written, it would make the behavior undefined, if under conditions when
pubsync()
should be called, but when in this scenarioos.rdbuf()
returns 0.This case is explicitly handled in
flush()
and needs to be taken care of. My suggested fix is:If
((os.flags() & ios_base::unitbuf) && !uncaught_exception()
&& os.rdbuf() != 0
) is true, callsos.flush()
os.rdbuf()->pubsync()
.Two secondary questions are:
- Should
pubsync()
be invoked in any case or shouldn't a base requirement for this trial be thatos.good() == true
as required in the originalflush()
case?- Since
uncaught_exception()
is explicitly tested, shouldn't a return value of -1 ofpubsync()
producesetstate(badbit)
(which may throwios_base::failure
)?
[ 2009-07 Frankfurt: ]
Daniel volunteered to modify the proposed resolution to address his two questions.
Move back to Open.
[ 2009-07-26 Daniel provided wording. Moved to Review. ]
[ 2009-10-13 Daniel adds: ]
This proposed wording is written to match the outcome of 397.
[ 2009 Santa Cruz: ]
Move to Open. Martin to propose updated wording that will also resolve issue 397 consistently.
[ 2010-02-15 Martin provided wording. ]
[ 2010 Pittsburgh: ]
Moved to Ready for Pittsburgh.
Proposed resolution:
Just before 31.5.4.3 [basic.ios.members] p. 2 insert a new paragraph:
Requires: If
(tiestr != 0)
istrue
,tiestr
must not be reachable by traversing the linked list of tied stream objects starting fromtiestr->tie()
.
Change [ostream::sentry] p. 4 as indicated:
If
((os.flags() & ios_base::unitbuf) && !uncaught_exception() && os.good())
istrue
, callsos.flush()
os.rdbuf()->pubsync()
. If that function returns -1 setsbadbit
inos.rdstate()
without propagating an exception.
Add after [ostream::sentry] p17, the following paragraph:
Throws: Nothing.