This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of New status.
ostream::sentry
destructor should handle exceptionsSection: 31.7.6.2.4 [ostream.sentry] Status: New Submitter: Jonathan Wakely Opened: 2025-01-14 Last modified: 2025-01-14
Priority: Not Prioritized
View other active issues in [ostream.sentry].
View all other issues in [ostream.sentry].
View all issues with New status.
Discussion:
LWG 397(i) suggested changing 31.7.6.2.4 [ostream.sentry] to
say that the ostream::sentry
destructor doesn't throw any exceptions.
That issue was closed as resolved by LWG 835(i) which included
the "Throws: Nothing" change to the sentry
destructor.
However, that part of the resolution never seems to have been applied to
the working draft. N3091 mentions applying LWG 835 for
N3090 but the destructor change is missing, maybe because
the paragraph for the sentry destructor had been renumbered from p17 to p4
and LWG 835 didn't show sufficient context to indicate the intended location.
The problem described in LWG 397(i) is still present:
the streambuf operations can fail, and the sentry needs to handle that.
The changes for LWG 835(i) ensure no exception is thrown if
rdbuf()->pubsync()
returns -1 on failure, but do nothing for
the case where it throws an exception (the original topic of LWG 397!).
Because C++11 made ~sentry
implicitly noexcept
,
an exception from rdbuf()->pubsync()
will terminate the process.
That needs to be fixed.
Libstdc++ does terminate if pubsync()
throws when called by ~sentry
.
Both MSVC and Libc++ silently swallow exceptions.
It seems preferable to handle the exception and report an error,
just as we do when pubsync()
returns -1.
Proposed resolution:
This wording is relative to N5001.
Modify 31.7.6.2.4 [ostream.sentry] as indicated:
~sentry();
-4- If(os.flags() & ios_base::unitbuf) && !uncaught_exceptions() && os.good()
istrue
, callsos.rdbuf()->pubsync()
. If that function returns −1 or exits via an exception, setsbadbit
inos.rdstate()
without propagating an exception.