Skip to content

Commit b8371e2

Browse files
committed
New issue from Jonathan: ostream::sentry destructor should handle exceptions
1 parent 99c61f6 commit b8371e2

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

xml/issue4188.xml

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
<?xml version='1.0' encoding='utf-8' standalone='no'?>
2+
<!DOCTYPE issue SYSTEM "lwg-issue.dtd">
3+
4+
<issue num="4188" status="New">
5+
<title><code>ostream::sentry</code> destructor should handle exceptions</title>
6+
<section><sref ref="[ostream.sentry]"/></section>
7+
<submitter>Jonathan Wakely</submitter>
8+
<date>14 Jan 2025</date>
9+
<priority>99</priority>
10+
11+
<discussion>
12+
<p>
13+
LWG <iref ref="397"/> suggested changing <sref ref="[ostream.sentry]"/> to
14+
say that the `ostream::sentry` destructor doesn't throw any exceptions.
15+
That issue was closed as resolved by LWG <iref ref="835"/> which included
16+
the "Throws: Nothing" change to the `sentry` destructor.
17+
However, that part of the resolution never seems to have been applied to
18+
the working draft. <paper num="N3091"/> mentions applying LWG 835 for
19+
<paper num="N3090"/> but the destructor change is missing, maybe because
20+
the paragraph for the sentry destructor had been renumbered from p17 to p4
21+
and LWG 835 didn't show sufficient context to indicate the intended location.
22+
</p>
23+
24+
<p>
25+
The problem described in LWG <iref ref="397"/> is still present:
26+
the streambuf operations can fail, and the sentry needs to handle that.
27+
The changes for LWG <iref ref="835"/> ensure no exception is thrown if
28+
<code>rdbuf()-&gt;pubsync()</code> returns -1 on failure, but do nothing for
29+
the case where it throws an exception (the original topic of LWG 397!).
30+
Because C++11 made `~sentry` implicitly `noexcept`,
31+
an exception from `rdbuf()->pubsync()` will terminate the process.
32+
That needs to be fixed.
33+
</p>
34+
35+
<p>
36+
Libstdc++ does terminate if `pubsync()` throws when called by `~sentry`.
37+
Both MSVC and Libc++ silently swallow exceptions.
38+
It seems preferable to handle the exception and report an error,
39+
just as we do when `pubsync()` returns -1.
40+
</p>
41+
42+
</discussion>
43+
44+
<resolution>
45+
<p>
46+
This wording is relative to <paper num="N5001"/>.
47+
</p>
48+
49+
<ol>
50+
<li><p>Modify <sref ref="[ostream.sentry]"/> as indicated:</p>
51+
52+
<blockquote>
53+
<pre><code>~sentry();</code></pre>
54+
<blockquote>
55+
-4- If
56+
<code>(os.flags() &amp; ios_base::unitbuf) &amp;&amp; !uncaught_exceptions() &amp;&amp; os.good()</code> is `true`, calls <code>os.rdbuf()-&gt;pubsync()</code>.
57+
If that function returns −1
58+
<ins> or exits via an exceptions</ins>,
59+
sets `badbit` in `os.rdstate()` without propagating an exception.
60+
</blockquote>
61+
</blockquote>
62+
</li>
63+
</ol>
64+
65+
</resolution>
66+
67+
</issue>

0 commit comments

Comments
 (0)