https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108561

            Bug ID: 108561
           Summary: std::endl causes a flush on a bad stream
           Product: gcc
           Version: unknown
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: lavr at ncbi dot nlm.nih.gov
  Target Milestone: ---

As implemented:

  template<typename _CharT, typename _Traits>
    inline basic_ostream<_CharT, _Traits>&
    endl(basic_ostream<_CharT, _Traits>& __os)
    { return flush(__os.put(__os.widen('\n'))); }

this code can cause flush() to be called for a stream that has gone bad during
the execution of put().  Note that put() constructs a sentry, which if it threw
an exception, would case the stream to get a badbit (the most severe case; but
other unsuccessful sentry construction errors fit the same pattern).  On the
other hand, flush() does not check for any such things -- there's no sentry
construction -- instead, it just blindly calls the underlying stream buffer's
pubsync().  The bottom line result is that the failed output is missing yet the
flush is still attempted, but the expected behavior is that the output should
be _followed_ by the flush.  Otherwise, the order of the expected I/O is wrong
(the flush appears out of order when put() failed).

A fix would be to do something like this:

__os = __os.put(__os.widen('\n');
return __os ? flush(__os) : __os;

Reply via email to