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.

4188. ostream::sentry destructor should handle exceptions

Section: 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.

  1. Modify 31.7.6.2.4 [ostream.sentry] as indicated:

    ~sentry();
    -4- If (os.flags() & ios_base::unitbuf) && !uncaught_exceptions() && os.good() is true, calls os.rdbuf()->pubsync(). If that function returns −1 or exits via an exception, sets badbit in os.rdstate() without propagating an exception.