Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Question on library issue #581, using a sentry in flush()

11 views
Skip to first unread message

Bo Persson

unread,
May 2, 2008, 6:43:30 AM5/2/08
to
This would have gone to comp.std.c++, had it been active.


The resolution to issue 581

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2578.html#581

requires that basic_ostream::flush creates a sentry object to verify
the stream state.

However, for streams with the unit_buf flag set, like std::err, the
destructor of the sentry object will again call flush(). This seems to
create an infinite recursion for

std::cerr << std::flush;

or even

std::cerr << "Some message" << std::endl;


Have I missed something here?


Bo Persson

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

Francis Glassborow

unread,
May 2, 2008, 2:46:04 PM5/2/08
to
Bo Persson wrote:
> This would have gone to comp.std.c++, had it been active.

Is it possible to find out what happened to comp.std.c++? Even better
would be to revive it as it provided an important and useful service
(and as we get closer to C++0x, it becomes more important to have a
newsgroup that deals with standard issues rather than coding ones)

Daniel Krügler

unread,
May 3, 2008, 8:13:27 AM5/3/08
to
On 2 Mai, 12:43, "Bo Persson" <b...@gmb.dk> wrote:
> The resolution to issue 581
>
> http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2578.html#581
>
> requires that basic_ostream::flush creates a sentry object to verify
> the stream state.
>
> However, for streams with the unit_buf flag set, like std::err, the
> destructor of the sentry object will again call flush(). This seems to
> create an infinite recursion for
>
> std::cerr << std::flush;
>
> or even
>
> std::cerr << "Some message" << std::endl;
>
> Have I missed something here?

No, I agree with your analysis. Additionally the proposed
resolution references the wrong section by saying in
[ostream.unformatted]/7:

"Behaves as an unformatted output function (as described in
27.6.2.6.1,
paragraph 1).[..]"

because 27.6.2.6.1/p.1 describes the semantic of *formatted*
output functions.

Greetings from Bremen,

Daniel Krügler

se...@roguewave.com

unread,
May 8, 2008, 11:43:27 PM5/8/08
to
On May 3, 6:13 am, Daniel Krügler <daniel.krueg...@googlemail.com>
wrote:

> On 2 Mai, 12:43, "Bo Persson" <b...@gmb.dk> wrote:
>
>
>
> > The resolution to issue 581
>
> >http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2578.html#581
>
> > requires that basic_ostream::flush creates a sentry object to verify
> > the stream state.
>
> > However, for streams with the unit_buf flag set, like std::err, the
> > destructor of the sentry object will again call flush(). This seems to
> > create an infinite recursion for
>
> > std::cerr << std::flush;
>
> > or even
>
> > std::cerr << "Some message" << std::endl;
>
> > Have I missed something here?

The text in [ostream::sentry], p4 should probably be changed
to read something like

If ((os.flags() & ios_base::unitbuf) && !uncaught_exception())
is true, calls os.rdbuf()->pubsync().

to avoid this. Let me fix it along with the similar problem
with the tied stream.

>
> No, I agree with your analysis. Additionally the proposed
> resolution references the wrong section by saying in
> [ostream.unformatted]/7:
>
> "Behaves as an unformatted output function (as described in
> 27.6.2.6.1,
> paragraph 1).[..]"
>
> because 27.6.2.6.1/p.1 describes the semantic of *formatted*
> output functions.

I think the numbers have changed between C++ 98 and the latest
working paper. We should be using section names instead of
numbers, they don't change (i.e., [ostream.unformatted]).

Daniel Krügler

unread,
May 9, 2008, 11:23:39 PM5/9/08
to
On 9 Mai, 05:43, "se...@roguewave.com" <se...@roguewave.com> wrote:
> The text in [ostream::sentry], p4 should probably be changed
> to read something like
>
> If ((os.flags() & ios_base::unitbuf) && !uncaught_exception())
> is true, calls os.rdbuf()->pubsync().
>
> to avoid this. Let me fix it along with the similar problem
> with the tied stream.

I agree with this..

> I think the numbers have changed between C++ 98 and the latest
> working paper. We should be using section names instead of
> numbers, they don't change (i.e., [ostream.unformatted]).

You are right in both points, as I just notice.

Let me add three related questions, which came to me while
I was searching of references to flush:

1) N2588, [istream::sentry]/2, describes effects in terms of
flush on the result of is.tie(). Wouldn't it make sense to
refer here to is.tie()->rdbuf()->pubsync() as well? All other
effects of this c'tor are already based on rdbuf() functions
(of is).

2) I think that footnote 321, N2588, needs also to be adapted.

3) I have a question regarding [ios::Init]/4: The effects clause
of ~Init() says:

"Destroys an object of class Init. The function subtracts one from
the value stored in init_cnt and, if the resulting stored value is
one, calls cout.flush(), cerr.flush(), clog.flush(), wcout.flush(),
wcerr.flush(), wclog.flush()."

But because flush can (indirectly) throw a ios_base::failure,
I see two problems:

1) Does the standard need to rule this exception, although it
happens after program execution ([iostream.objects]/2)?

2) Actually worse seems to me that the standard seems not to
provide guarantees that such an intermediate throw does not
influence the outstanding flushs. What I mean is the following:
Consider that

cout.flush(), cerr.flush(), ..

are called and cout.flush() throws. Will cerr.flush() and
all remaining flush()'s still be called? I would like to
hear such statement, but during a short survey I couldn't
find anything.

[Please note that these "issues" of (3) are not new, but
I just stumbled across them]

Greetings from Bremen,

Daniel Krügler


0 new messages