1 |
742 |
jeremybenn |
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2 |
|
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
3 |
|
|
<html xmlns="http://www.w3.org/1999/xhtml"><head><title>Exceptions</title><meta name="generator" content="DocBook XSL-NS Stylesheets V1.76.1"/><meta name="keywords" content=" C++ , exception , error , exception neutrality , exception safety , exception propagation , -fno-exceptions "/><meta name="keywords" content=" ISO C++ , library "/><meta name="keywords" content=" ISO C++ , runtime , library "/><link rel="home" href="../index.html" title="The GNU C++ Library"/><link rel="up" href="using.html" title="Chapter 3. Using"/><link rel="prev" href="using_concurrency.html" title="Concurrency"/><link rel="next" href="debug.html" title="Debugging Support"/></head><body><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Exceptions</th></tr><tr><td align="left"><a accesskey="p" href="using_concurrency.html">Prev</a> </td><th width="60%" align="center">Chapter 3. Using</th><td align="right"> <a accesskey="n" href="debug.html">Next</a></td></tr></table><hr/></div><div class="section" title="Exceptions"><div class="titlepage"><div><div><h2 class="title"><a id="manual.intro.using.exceptions"/>Exceptions</h2></div></div></div><p>
|
4 |
|
|
The C++ language provides language support for stack unwinding
|
5 |
|
|
with <code class="literal">try</code> and <code class="literal">catch</code> blocks and
|
6 |
|
|
the <code class="literal">throw</code> keyword.
|
7 |
|
|
</p><p>
|
8 |
|
|
These are very powerful constructs, and require some thought when
|
9 |
|
|
applied to the standard library in order to yield components that work
|
10 |
|
|
efficiently while cleaning up resources when unexpectedly killed via
|
11 |
|
|
exceptional circumstances.
|
12 |
|
|
</p><p>
|
13 |
|
|
Two general topics of discussion follow:
|
14 |
|
|
exception neutrality and exception safety.
|
15 |
|
|
</p><div class="section" title="Exception Safety"><div class="titlepage"><div><div><h3 class="title"><a id="intro.using.exception.safety"/>Exception Safety</h3></div></div></div><p>
|
16 |
|
|
What is exception-safe code?
|
17 |
|
|
</p><p>
|
18 |
|
|
Will define this as reasonable and well-defined behavior by classes
|
19 |
|
|
and functions from the standard library when used by user-defined
|
20 |
|
|
classes and functions that are themselves exception safe.
|
21 |
|
|
</p><p>
|
22 |
|
|
Please note that using exceptions in combination with templates
|
23 |
|
|
imposes an additional requirement for exception
|
24 |
|
|
safety. Instantiating types are required to have destructors that
|
25 |
|
|
do no throw.
|
26 |
|
|
</p><p>
|
27 |
|
|
Using the layered approach from Abrahams, can classify library
|
28 |
|
|
components as providing set levels of safety. These will be called
|
29 |
|
|
exception guarantees, and can be divided into three categories.
|
30 |
|
|
</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p>
|
31 |
|
|
One. Don't throw.
|
32 |
|
|
</p><p>
|
33 |
|
|
As specified in 23.2.1 general container requirements. Applicable
|
34 |
|
|
to container and string classes.
|
35 |
|
|
</p><p>
|
36 |
|
|
Member
|
37 |
|
|
functions <code class="function">erase</code>, <code class="function">pop_back</code>, <code class="function">pop_front</code>, <code class="function">swap</code>, <code class="function">clear</code>. And <span class="type">iterator</span>
|
38 |
|
|
copy constructor and assignment operator.
|
39 |
|
|
</p></li><li class="listitem"><p>
|
40 |
|
|
Two. Don't leak resources when exceptions are thrown. This is
|
41 |
|
|
also referred to as the <span class="quote">“<span class="quote">basic</span>”</span> exception safety guarantee.
|
42 |
|
|
</p><p>
|
43 |
|
|
This applicable throughout the standard library.
|
44 |
|
|
</p></li><li class="listitem"><p>
|
45 |
|
|
Three. Commit-or-rollback semantics. This is
|
46 |
|
|
referred to as <span class="quote">“<span class="quote">strong</span>”</span> exception safety guarantee.
|
47 |
|
|
</p><p>
|
48 |
|
|
As specified in 23.2.1 general container requirements. Applicable
|
49 |
|
|
to container and string classes.
|
50 |
|
|
</p><p>
|
51 |
|
|
Member functions <code class="function">insert</code> of a single
|
52 |
|
|
element, <code class="function">push_back</code>, <code class="function">push_front</code>,
|
53 |
|
|
and <code class="function">rehash</code>.
|
54 |
|
|
</p></li></ul></div></div><div class="section" title="Exception Neutrality"><div class="titlepage"><div><div><h3 class="title"><a id="intro.using.exception.propagating"/>Exception Neutrality</h3></div></div></div><p>
|
55 |
|
|
Simply put, once thrown an exception object should continue in
|
56 |
|
|
flight unless handled explicitly. In practice, this means
|
57 |
|
|
propagating exceptions should not be swallowed in
|
58 |
|
|
gratuitous <code class="literal">catch(...)</code> blocks. Instead,
|
59 |
|
|
matching <code class="literal">try</code> and <code class="literal">catch</code>
|
60 |
|
|
blocks should have specific catch handlers and allow un-handed
|
61 |
|
|
exception objects to propagate. If a
|
62 |
|
|
terminating <code class="literal">catch(...)</code> blocks exist then it
|
63 |
|
|
should end with a <code class="literal">throw</code> to re-throw the current
|
64 |
|
|
exception.
|
65 |
|
|
</p><p>
|
66 |
|
|
Why do this?
|
67 |
|
|
</p><p>
|
68 |
|
|
By allowing exception objects to propagate, a more flexible
|
69 |
|
|
approach to error handling is made possible (although not
|
70 |
|
|
required.) Instead of dealing with an error immediately, one can
|
71 |
|
|
allow the exception to propagate up until sufficient context is
|
72 |
|
|
available and the choice of exiting or retrying can be made in an
|
73 |
|
|
informed manner.
|
74 |
|
|
</p><p>
|
75 |
|
|
Unfortunately, this tends to be more of a guideline than a strict
|
76 |
|
|
rule as applied to the standard library. As such, the following is
|
77 |
|
|
a list of known problem areas where exceptions are not propagated.
|
78 |
|
|
</p><div class="itemizedlist"><ul class="itemizedlist"><li class="listitem"><p>
|
79 |
|
|
Input/Output
|
80 |
|
|
</p><p>
|
81 |
|
|
The destructor <code class="function">ios_base::Init::~Init()</code>
|
82 |
|
|
swallows all exceptions from <code class="function">flush</code> called on
|
83 |
|
|
all open streams at termination.
|
84 |
|
|
</p><p>
|
85 |
|
|
All formatted input in <code class="classname">basic_istream</code> or
|
86 |
|
|
formatted output in <code class="classname">basic_ostream</code> can be
|
87 |
|
|
configured to swallow exceptions
|
88 |
|
|
when <code class="function">exceptions</code> is set to
|
89 |
|
|
ignore <span class="type">ios_base::badbit</span>.
|
90 |
|
|
</p><p>
|
91 |
|
|
Functions that have been registered
|
92 |
|
|
with <code class="function">ios_base::register_callback</code> swallow all
|
93 |
|
|
exceptions when called as part of a callback event.
|
94 |
|
|
</p><p>
|
95 |
|
|
When closing the underlying
|
96 |
|
|
file, <code class="function">basic_filebuf::close</code> will swallow
|
97 |
|
|
(non-cancellation) exceptions thrown and return <code class="literal">NULL</code>.
|
98 |
|
|
</p></li><li class="listitem"><p>
|
99 |
|
|
Thread
|
100 |
|
|
</p><p>
|
101 |
|
|
The constructors of <code class="classname">thread</code> that take a
|
102 |
|
|
callable function argument swallow all exceptions resulting from
|
103 |
|
|
executing the function argument.
|
104 |
|
|
</p></li></ul></div></div><div class="section" title="Doing without"><div class="titlepage"><div><div><h3 class="title"><a id="intro.using.exception.no"/>Doing without</h3></div></div></div><p>
|
105 |
|
|
C++ is a language that strives to be as efficient as is possible
|
106 |
|
|
in delivering features. As such, considerable care is used by both
|
107 |
|
|
language implementer and designers to make sure unused features
|
108 |
|
|
not impose hidden or unexpected costs. The GNU system tries to be
|
109 |
|
|
as flexible and as configurable as possible. So, it should come as
|
110 |
|
|
no surprise that GNU C++ provides an optional language extension,
|
111 |
|
|
spelled <code class="literal">-fno-exceptions</code>, as a way to excise the
|
112 |
|
|
implicitly generated magic necessary to
|
113 |
|
|
support <code class="literal">try</code> and <code class="literal">catch</code> blocks
|
114 |
|
|
and thrown objects. (Language support
|
115 |
|
|
for <code class="literal">-fno-exceptions</code> is documented in the GNU
|
116 |
|
|
GCC <a class="link" href="http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options">manual</a>.)
|
117 |
|
|
</p><p>Before detailing the library support
|
118 |
|
|
for <code class="literal">-fno-exceptions</code>, first a passing note on
|
119 |
|
|
the things lost when this flag is used: it will break exceptions
|
120 |
|
|
trying to pass through code compiled
|
121 |
|
|
with <code class="literal">-fno-exceptions</code> whether or not that code
|
122 |
|
|
has any <code class="literal">try</code> or <code class="literal">catch</code>
|
123 |
|
|
constructs. If you might have some code that throws, you shouldn't
|
124 |
|
|
use <code class="literal">-fno-exceptions</code>. If you have some code that
|
125 |
|
|
uses <code class="literal">try</code> or <code class="literal">catch</code>, you
|
126 |
|
|
shouldn't use <code class="literal">-fno-exceptions</code>.
|
127 |
|
|
</p><p>
|
128 |
|
|
And what it to be gained, tinkering in the back alleys with a
|
129 |
|
|
language like this? Exception handling overhead can be measured
|
130 |
|
|
in the size of the executable binary, and varies with the
|
131 |
|
|
capabilities of the underlying operating system and specific
|
132 |
|
|
configuration of the C++ compiler. On recent hardware with GNU
|
133 |
|
|
system software of the same age, the combined code and data size
|
134 |
|
|
overhead for enabling exception handling is around 7%. Of course,
|
135 |
|
|
if code size is of singular concern than using the appropriate
|
136 |
|
|
optimizer setting with exception handling enabled
|
137 |
|
|
(ie, <code class="literal">-Os -fexceptions</code>) may save up to twice
|
138 |
|
|
that, and preserve error checking.
|
139 |
|
|
</p><p>
|
140 |
|
|
So. Hell bent, we race down the slippery track, knowing the brakes
|
141 |
|
|
are a little soft and that the right front wheel has a tendency to
|
142 |
|
|
wobble at speed. Go on: detail the standard library support
|
143 |
|
|
for <code class="literal">-fno-exceptions</code>.
|
144 |
|
|
</p><p>
|
145 |
|
|
In sum, valid C++ code with exception handling is transformed into
|
146 |
|
|
a dialect without exception handling. In detailed steps: all use
|
147 |
|
|
of the C++
|
148 |
|
|
keywords <code class="literal">try</code>, <code class="literal">catch</code>,
|
149 |
|
|
and <code class="literal">throw</code> in the standard library have been
|
150 |
|
|
permanently replaced with the pre-processor controlled equivalents
|
151 |
|
|
spelled <code class="literal">__try</code>, <code class="literal">__catch</code>,
|
152 |
|
|
and <code class="literal">__throw_exception_again</code>. They are defined
|
153 |
|
|
as follows.
|
154 |
|
|
</p><pre class="programlisting">
|
155 |
|
|
#ifdef __EXCEPTIONS
|
156 |
|
|
# define __try try
|
157 |
|
|
# define __catch(X) catch(X)
|
158 |
|
|
# define __throw_exception_again throw
|
159 |
|
|
#else
|
160 |
|
|
# define __try if (true)
|
161 |
|
|
# define __catch(X) if (false)
|
162 |
|
|
# define __throw_exception_again
|
163 |
|
|
#endif
|
164 |
|
|
</pre><p>
|
165 |
|
|
In addition, for every object derived from
|
166 |
|
|
class <code class="classname">exception</code>, there exists a corresponding
|
167 |
|
|
function with C language linkage. An example:
|
168 |
|
|
</p><pre class="programlisting">
|
169 |
|
|
#ifdef __EXCEPTIONS
|
170 |
|
|
void __throw_bad_exception(void)
|
171 |
|
|
{ throw bad_exception(); }
|
172 |
|
|
#else
|
173 |
|
|
void __throw_bad_exception(void)
|
174 |
|
|
{ abort(); }
|
175 |
|
|
#endif
|
176 |
|
|
</pre><p>
|
177 |
|
|
The last language feature needing to be transformed
|
178 |
|
|
by <code class="literal">-fno-exceptions</code> is treatment of exception
|
179 |
|
|
specifications on member functions. Fortunately, the compiler deals
|
180 |
|
|
with this by ignoring exception specifications and so no alternate
|
181 |
|
|
source markup is needed.
|
182 |
|
|
</p><p>
|
183 |
|
|
By using this combination of language re-specification by the
|
184 |
|
|
compiler, and the pre-processor tricks and the functional
|
185 |
|
|
indirection layer for thrown exception objects by the library,
|
186 |
|
|
libstdc++ files can be compiled
|
187 |
|
|
with <code class="literal">-fno-exceptions</code>.
|
188 |
|
|
</p><p>
|
189 |
|
|
User code that uses C++ keywords
|
190 |
|
|
like <code class="literal">throw</code>, <code class="literal">try</code>,
|
191 |
|
|
and <code class="literal">catch</code> will produce errors even if the user
|
192 |
|
|
code has included libstdc++ headers and is using constructs
|
193 |
|
|
like <code class="classname">basic_iostream</code>. Even though the standard
|
194 |
|
|
library has been transformed, user code may need modification. User
|
195 |
|
|
code that attempts or expects to do error checking on standard
|
196 |
|
|
library components compiled with exception handling disabled should
|
197 |
|
|
be evaluated and potentially made conditional.
|
198 |
|
|
</p><p>
|
199 |
|
|
Some issues remain with this approach (see bugzilla entry
|
200 |
|
|
25191). Code paths are not equivalent, in
|
201 |
|
|
particular <code class="literal">catch</code> blocks are not evaluated. Also
|
202 |
|
|
problematic are <code class="literal">throw</code> expressions expecting a
|
203 |
|
|
user-defined throw handler. Known problem areas in the standard
|
204 |
|
|
library include using an instance
|
205 |
|
|
of <code class="classname">basic_istream</code>
|
206 |
|
|
with <code class="function">exceptions</code> set to specific
|
207 |
|
|
<span class="type">ios_base::iostate</span> conditions, or
|
208 |
|
|
cascading <code class="literal">catch</code> blocks that dispatch error
|
209 |
|
|
handling or recovery efforts based on the type of exception object
|
210 |
|
|
thrown.
|
211 |
|
|
</p><p>
|
212 |
|
|
Oh, and by the way: none of this hackery is at all
|
213 |
|
|
special. (Although perhaps well-deserving of a raised eyebrow.)
|
214 |
|
|
Support continues to evolve and may change in the future. Similar
|
215 |
|
|
and even additional techniques are used in other C++ libraries and
|
216 |
|
|
compilers.
|
217 |
|
|
</p><p>
|
218 |
|
|
C++ hackers with a bent for language and control-flow purity have
|
219 |
|
|
been successfully consoled by grizzled C veterans lamenting the
|
220 |
|
|
substitution of the C language keyword
|
221 |
|
|
<code class="literal">const</code> with the uglified
|
222 |
|
|
doppelganger <code class="literal">__const</code>.
|
223 |
|
|
</p></div><div class="section" title="Compatibility"><div class="titlepage"><div><div><h3 class="title"><a id="intro.using.exception.compat"/>Compatibility</h3></div></div></div><div class="section" title="With C"><div class="titlepage"><div><div><h4 class="title"><a id="using.exception.compat.c"/>With <code class="literal">C</code></h4></div></div></div><p>
|
224 |
|
|
C language code that is expecting to interoperate with C++ should be
|
225 |
|
|
compiled with <code class="literal">-fexceptions</code>. This will make
|
226 |
|
|
debugging a C language function called as part of C++-induced stack
|
227 |
|
|
unwinding possible.
|
228 |
|
|
</p><p>
|
229 |
|
|
In particular, unwinding into a frame with no exception handling
|
230 |
|
|
data will cause a runtime abort. If the unwinder runs out of unwind
|
231 |
|
|
info before it finds a handler, <code class="function">std::terminate()</code>
|
232 |
|
|
is called.
|
233 |
|
|
</p><p>
|
234 |
|
|
Please note that most development environments should take care of
|
235 |
|
|
getting these details right. For GNU systems, all appropriate parts
|
236 |
|
|
of the GNU C library are already compiled
|
237 |
|
|
with <code class="literal">-fexceptions</code>.
|
238 |
|
|
</p></div><div class="section" title="With POSIX thread cancellation"><div class="titlepage"><div><div><h4 class="title"><a id="using.exception.compat.posix"/>With <code class="literal">POSIX</code> thread cancellation</h4></div></div></div><p>
|
239 |
|
|
GNU systems re-use some of the exception handling mechanisms to
|
240 |
|
|
track control flow for <code class="literal">POSIX</code> thread cancellation.
|
241 |
|
|
</p><p>
|
242 |
|
|
Cancellation points are functions defined by POSIX as worthy of
|
243 |
|
|
special treatment. The standard library may use some of these
|
244 |
|
|
functions to implement parts of the ISO C++ standard or depend on
|
245 |
|
|
them for extensions.
|
246 |
|
|
</p><p>
|
247 |
|
|
Of note:
|
248 |
|
|
</p><p>
|
249 |
|
|
<code class="function">nanosleep</code>,
|
250 |
|
|
<code class="function">read</code>, <code class="function">write</code>, <code class="function">open</code>, <code class="function">close</code>,
|
251 |
|
|
and <code class="function">wait</code>.
|
252 |
|
|
</p><p>
|
253 |
|
|
The parts of libstdc++ that use C library functions marked as
|
254 |
|
|
cancellation points should take pains to be exception neutral.
|
255 |
|
|
Failing this, <code class="literal">catch</code> blocks have been augmented to
|
256 |
|
|
show that the POSIX cancellation object is in flight.
|
257 |
|
|
</p><p>
|
258 |
|
|
This augmentation adds a <code class="literal">catch</code> block
|
259 |
|
|
for <code class="classname">__cxxabiv1::__forced_unwind</code>, which is the
|
260 |
|
|
object representing the POSIX cancellation object. Like so:
|
261 |
|
|
</p><pre class="programlisting">
|
262 |
|
|
catch(const __cxxabiv1::__forced_unwind&)
|
263 |
|
|
{
|
264 |
|
|
this->_M_setstate(ios_base::badbit);
|
265 |
|
|
throw;
|
266 |
|
|
}
|
267 |
|
|
catch(...)
|
268 |
|
|
{ this->_M_setstate(ios_base::badbit); }
|
269 |
|
|
</pre></div></div><div class="bibliography" title="Bibliography"><div class="titlepage"><div><div><h3 class="title"><a id="using.exceptions.biblio"/>Bibliography</h3></div></div></div><div class="biblioentry" title="System Interface Definitions, Issue 7 (IEEE Std. 1003.1-2008)"><a id="id483021"/><p><span class="title"><em>
|
270 |
|
|
<a class="link" href="http://www.opengroup.org/austin">
|
271 |
|
|
System Interface Definitions, Issue 7 (IEEE Std. 1003.1-2008)
|
272 |
|
|
</a>
|
273 |
|
|
</em>. </span><span class="pagenums">
|
274 |
|
|
2.9.5 Thread Cancellation
|
275 |
|
|
. </span><span class="copyright">Copyright © 2008
|
276 |
|
|
The Open Group/The Institute of Electrical and Electronics
|
277 |
|
|
Engineers, Inc.
|
278 |
|
|
. </span></p></div><div class="biblioentry" title="Error and Exception Handling"><a id="id483051"/><p><span class="title"><em>
|
279 |
|
|
<a class="link" href="http://www.boost.org/community/error_handling.html">
|
280 |
|
|
Error and Exception Handling
|
281 |
|
|
</a>
|
282 |
|
|
</em>. </span><span class="author"><span class="firstname">David</span> <span class="surname">Abrahams </span>. </span><span class="publisher"><span class="publishername">
|
283 |
|
|
Boost
|
284 |
|
|
. </span></span></p></div><div class="biblioentry" title="Exception-Safety in Generic Components"><a id="id483082"/><p><span class="title"><em>
|
285 |
|
|
<a class="link" href="http://www.boost.org/community/exception_safety.html">
|
286 |
|
|
Exception-Safety in Generic Components
|
287 |
|
|
</a>
|
288 |
|
|
</em>. </span><span class="author"><span class="firstname">David</span> <span class="surname">Abrahams</span>. </span><span class="publisher"><span class="publishername">
|
289 |
|
|
Boost
|
290 |
|
|
. </span></span></p></div><div class="biblioentry" title="Standard Library Exception Policy"><a id="id483113"/><p><span class="title"><em>
|
291 |
|
|
<a class="link" href="www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1077.pdf">
|
292 |
|
|
Standard Library Exception Policy
|
293 |
|
|
</a>
|
294 |
|
|
</em>. </span><span class="author"><span class="firstname">Matt</span> <span class="surname">Austern</span>. </span><span class="publisher"><span class="publishername">
|
295 |
|
|
WG21 N1077
|
296 |
|
|
. </span></span></p></div><div class="biblioentry" title="ia64 c++ abi exception handling"><a id="id483144"/><p><span class="title"><em>
|
297 |
|
|
<a class="link" href="http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00661.html">
|
298 |
|
|
ia64 c++ abi exception handling
|
299 |
|
|
</a>
|
300 |
|
|
</em>. </span><span class="author"><span class="firstname">Richard</span> <span class="surname">Henderson</span>. </span><span class="publisher"><span class="publishername">
|
301 |
|
|
GNU
|
302 |
|
|
. </span></span></p></div><div class="biblioentry" title="Appendix E: Standard-Library Exception Safety"><a id="id483175"/><p><span class="title"><em>
|
303 |
|
|
<a class="link" href="http://www.research.att.com/~bs/3rd_safe.pdf">
|
304 |
|
|
Appendix E: Standard-Library Exception Safety
|
305 |
|
|
</a>
|
306 |
|
|
</em>. </span><span class="author"><span class="firstname">Bjarne</span> <span class="surname">Stroustrup</span>. </span></p></div><div class="biblioentry"><a id="id483198"/><p><span class="citetitle"><em class="citetitle">
|
307 |
|
|
Exceptional C++
|
308 |
|
|
</em>. </span><span class="pagenums">
|
309 |
|
|
Exception-Safety Issues and Techniques
|
310 |
|
|
. </span><span class="author"><span class="firstname">Herb</span> <span class="surname">Sutter</span>. </span></p></div><div class="biblioentry" title="GCC Bug 25191: exception_defines.h #defines try/catch"><a id="id483218"/><p><span class="title"><em>
|
311 |
|
|
<a class="link" href="http://gcc.gnu.org/PR25191">
|
312 |
|
|
GCC Bug 25191: exception_defines.h #defines try/catch
|
313 |
|
|
</a>
|
314 |
|
|
</em>. </span></p></div></div></div><div class="navfooter"><hr/><table width="100%" summary="Navigation footer"><tr><td align="left"><a accesskey="p" href="using_concurrency.html">Prev</a> </td><td align="center"><a accesskey="u" href="using.html">Up</a></td><td align="right"> <a accesskey="n" href="debug.html">Next</a></td></tr><tr><td align="left" valign="top">Concurrency </td><td align="center"><a accesskey="h" href="../index.html">Home</a></td><td align="right" valign="top"> Debugging Support</td></tr></table></div></body></html>
|