Created on 2008-05-17.00:00:00 last changed 161 months ago
Proposed resolution:
Just before [basic.ios.members] p. 2 insert a new paragraph:
Requires: If (tiestr != 0) is true, tiestr must not be reachable by traversing the linked list of tied stream objects starting from tiestr->tie().
Change [ostream::sentry] p. 4 as indicated:
If ((os.flags() & ios_base::unitbuf) && !uncaught_exception() && os.good()) is true, calls
os.flush()os.rdbuf()->pubsync(). If that function returns -1 sets badbit in os.rdstate() without propagating an exception.
Add after [ostream::sentry] p17, the following paragraph:
Throws: Nothing.
[ 2010 Pittsburgh: ]
Moved to Ready for Pittsburgh.
[ 2010-02-15 Martin provided wording. ]
[ 2009 Santa Cruz: ]
Move to Open. Martin to propose updated wording that will also resolve issue 397 consistently.
[ 2009-10-13 Daniel adds: ]
This proposed wording is written to match the outcome of 397.
[ 2009-07-26 Daniel provided wording. Moved to Review. ]
[ 2009-07 Frankfurt: ]
Daniel volunteered to modify the proposed resolution to address his two questions.
Move back to Open.
[ 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 scenario os.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, calls
os.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 that os.good() == true as required in the original flush() case?
- Since uncaught_exception() is explicitly tested, shouldn't a return value of -1 of pubsync() produce setstate(badbit) (which may throw ios_base::failure)?
[ Batavia (2009-05): ]
We agree with the proposed resolution. Move to Review.
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"; }
History | |||
---|---|---|---|
Date | User | Action | Args |
2011-08-23 20:07:26 | admin | set | status: wp -> c++11 |
2010-10-21 18:28:33 | admin | set | messages: + msg3996 |
2010-10-21 18:28:33 | admin | set | messages: + msg3995 |
2010-10-21 18:28:33 | admin | set | messages: + msg3994 |
2010-10-21 18:28:33 | admin | set | messages: + msg3993 |
2010-10-21 18:28:33 | admin | set | messages: + msg3992 |
2010-10-21 18:28:33 | admin | set | messages: + msg3991 |
2010-10-21 18:28:33 | admin | set | messages: + msg3990 |
2010-10-21 18:28:33 | admin | set | messages: + msg3989 |
2010-10-21 18:28:33 | admin | set | messages: + msg3988 |
2008-05-17 00:00:00 | admin | create |