using_exceptions.xml revision 1.1
1<sect1 id="manual.intro.using.exceptions" xreflabel="Using Exceptions">
2<?dbhtml filename="using_exceptions.html"?>
3
4<sect1info>
5  <keywordset>
6    <keyword>
7      C++
8    </keyword>
9    <keyword>
10      exception
11    </keyword>
12    <keyword>
13      error
14    </keyword>
15    <keyword>
16      exception neutrality
17    </keyword>
18    <keyword>
19      exception safety
20    </keyword>
21    <keyword>
22      exception propagation
23    </keyword>
24    <keyword>
25      -fno-exceptions
26    </keyword>
27  </keywordset>
28</sect1info>
29
30<title>Exceptions</title>
31
32<para>
33The C++ language provides language support for stack unwinding
34with <literal>try</literal> and <literal>catch</literal> blocks and
35the <literal>throw</literal> keyword.
36</para>
37
38<para>
39These are very powerful constructs, and require some thought when
40applied to the standard library in order to yield components that work
41efficiently while cleaning up resources when unexpectedly killed via
42exceptional circumstances.
43</para>
44
45<para>
46Two general topics of discussion follow:
47exception neutrality and exception safety.
48</para>
49
50
51<sect2 id="intro.using.exception.safety" xreflabel="Exception Safety">
52<title>Exception Safety</title>
53
54  <para>
55    What is exception-safe code?
56  </para>
57
58  <para>
59    Will define this as reasonable and well-defined behavior by classes
60    and functions from the standard library when used by user-defined
61    classes and functions that are themselves exception safe.
62  </para>
63
64  <para>
65    Please note that using exceptions in combination with templates
66    imposes an additional requirement for exception
67    safety. Instantiating types are required to have destructors that
68    do no throw.
69  </para>
70
71  <para>
72    Using the layered approach from Abrahams, can classify library
73    components as providing set levels of safety. These will be called
74    exception guarantees, and can be divided into three categories.
75  </para>
76
77<itemizedlist>
78
79  <listitem>
80  <para>
81    One. Don't throw.
82  </para>
83  <para>
84    As specified in 23.2.1 general container requirements. Applicable
85    to container and string classes.
86  </para>
87  <para>
88    Member
89    functions <function>erase</function>, <function>pop_back</function>, <function>pop_front</function>, <function>swap</function>, <function>clear</function>. And <type>iterator</type>
90    copy constructor and assignment operator.
91  </para>
92  </listitem>
93
94  <listitem>
95  <para>
96    Two. Don't leak resources when exceptions are thrown. This is
97    also referred to as the <quote>basic</quote> exception safety guarantee.
98  </para>
99
100  <para>
101    This applicable throughout the standard library.
102  </para>
103  </listitem>
104
105  <listitem>
106  <para>
107    Three. Commit-or-rollback semantics.  This is
108    referred to as <quote>strong</quote> exception safety guarantee.
109  </para>
110
111  <para>
112    As specified in 23.2.1 general container requirements. Applicable
113    to container and string classes.
114  </para>
115  <para>
116    Member functions <function>insert</function> of a single
117    element, <function>push_back</function>, <function>push_front</function>,
118    and <function>rehash</function>.
119  </para>
120
121  </listitem>
122</itemizedlist>
123
124</sect2>
125
126
127<sect2 id="intro.using.exception.propagating" xreflabel="Exceptions Neutrality">
128<title>Exception Neutrality</title>
129  <para>
130    Simply put, once thrown an exception object should continue in
131    flight unless handled explicitly. In practice, this means
132    propagating exceptions should not be swallowed in
133    gratuitous <literal>catch(...)</literal> blocks. Instead,
134    matching <literal>try</literal> and <literal>catch</literal>
135    blocks should have specific catch handlers and allow un-handed
136    exception objects to propagate. If a
137    terminating <literal>catch(...)</literal> blocks exist then it
138    should end with a <literal>throw</literal> to re-throw the current
139    exception.
140  </para>
141
142  <para>
143    Why do this?
144  </para>
145
146  <para>
147    By allowing exception objects to propagate, a more flexible
148    approach to error handling is made possible (although not
149    required.) Instead of dealing with an error immediately, one can
150    allow the exception to propagate up until sufficient context is
151    available and the choice of exiting or retrying can be made in an
152    informed manner.
153  </para>
154
155  <para>
156    Unfortunately, this tends to be more of a guideline than a strict
157    rule as applied to the standard library. As such, the following is
158    a list of known problem areas where exceptions are not propagated.
159  </para>
160
161<itemizedlist>
162  <listitem>
163    <para>
164      Input/Output
165    </para>
166  <para>
167    The destructor <function>ios_base::Init::~Init()</function>
168    swallows all exceptions from <function>flush</function> called on
169    all open streams at termination.
170  </para>
171
172  <para>
173    All formatted input in <classname>basic_istream</classname> or
174    formatted output in <classname>basic_ostream</classname> can be
175    configured to swallow exceptions
176    when <function>exceptions</function> is set to
177    ignore <type>ios_base::badbit</type>.
178  </para>
179
180  <para>
181    Functions that have been registered
182    with <function>ios_base::register_callback</function> swallow all
183    exceptions when called as part of a callback event.
184  </para>
185
186  <para>
187    When closing the underlying
188    file, <function>basic_filebuf::close</function> will swallow
189    (non-cancellation) exceptions thrown and return <literal>NULL</literal>.
190  </para>
191  </listitem>
192  <listitem>
193    <para>
194      Thread
195    </para>
196    <para>
197      The constructors of <classname>thread</classname> that take a
198      callable function argument swallow all exceptions resulting from
199      executing the function argument.
200    </para>
201  </listitem>
202</itemizedlist>
203
204</sect2>
205
206<sect2 id="intro.using.exception.no" xreflabel="-fno-exceptions">
207<title>Doing without</title>
208  <para>
209    C++ is a language that strives to be as efficient as is possible
210    in delivering features. As such, considerable care is used by both
211    language implementer and designers to make sure unused features
212    not impose hidden or unexpected costs. The GNU system tries to be
213    as flexible and as configurable as possible. So, it should come as
214    no surprise that GNU C++ provides an optional language extension,
215    spelled <literal>-fno-exceptions</literal>, as a way to excise the
216    implicitly generated magic necessary to
217    support <literal>try</literal> and <literal>catch</literal> blocks
218    and thrown objects. (Language support
219    for <literal>-fno-exceptions</literal> is documented in the GNU
220    GCC <ulink url="http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options">manual</ulink>.)
221  </para>
222
223  <para>Before detailing the library support
224    for <literal>-fno-exceptions</literal>, first a passing note on
225    the things lost when this flag is used: it will break exceptions
226    trying to pass through code compiled
227    with <literal>-fno-exceptions</literal> whether or not that code
228    has any <literal>try</literal> or <literal>catch</literal>
229    constructs. If you might have some code that throws, you shouldn't
230    use <literal>-fno-exceptions</literal>. If you have some code that
231    uses <literal>try</literal> or <literal>catch</literal>, you
232    shouldn't use <literal>-fno-exceptions</literal>.
233  </para>
234
235  <para>
236    And what it to be gained, tinkering in the back alleys with a
237    language like this? Exception handling overhead can be measured
238    in the size of the executable binary, and varies with the
239    capabilities of the underlying operating system and specific
240    configuration of the C++ compiler. On recent hardware with GNU
241    system software of the same age, the combined code and data size
242    overhead for enabling exception handling is around 7%. Of course,
243    if code size is of singular concern than using the appropriate
244    optimizer setting with exception handling enabled
245    (ie, <literal>-Os -fexceptions</literal>) may save up to twice
246    that, and preserve error checking.
247  </para>
248
249  <para>
250    So. Hell bent, we race down the slippery track, knowing the brakes
251    are a little soft and that the right front wheel has a tendency to
252    wobble at speed. Go on: detail the standard library support
253    for <literal>-fno-exceptions</literal>.
254  </para>
255
256  <para>
257    In sum, valid C++ code with exception handling is transformed into
258    a dialect without exception handling. In detailed steps: all use
259    of the C++
260    keywords <literal>try</literal>, <literal>catch</literal>,
261    and <literal>throw</literal> in the standard library have been
262    permanently replaced with the pre-processor controlled equivalents
263    spelled <literal>__try</literal>, <literal>__catch</literal>,
264    and <literal>__throw_exception_again</literal>. They are defined
265    as follows.
266  </para>
267
268<programlisting>
269#ifdef __EXCEPTIONS
270# define __try      try
271# define __catch(X) catch(X)
272# define __throw_exception_again throw
273#else
274# define __try      if (true)
275# define __catch(X) if (false)
276# define __throw_exception_again
277#endif
278</programlisting>
279
280<para>
281  In addition, for every object derived from
282  class <classname>exception</classname>, there exists a corresponding
283  function with C language linkage. An example:
284</para>
285
286<programlisting>
287#ifdef __EXCEPTIONS
288  void __throw_bad_exception(void)
289  { throw bad_exception(); }
290#else
291  void __throw_bad_exception(void)
292  { abort(); }
293#endif
294</programlisting>
295
296<para>
297  The last language feature needing to be transformed
298  by <literal>-fno-exceptions</literal> is treatment of exception
299  specifications on member functions. Fortunately, the compiler deals
300  with this by ignoring exception specifications and so no alternate
301  source markup is needed.
302</para>
303
304<para>
305  By using this combination of language re-specification by the
306  compiler, and the pre-processor tricks and the functional
307  indirection layer for thrown exception objects by the library,
308  libstdc++ files can be compiled
309  with <literal>-fno-exceptions</literal>.
310</para>
311
312<para>
313 User code that uses C++ keywords
314 like <literal>throw</literal>, <literal>try</literal>,
315 and <literal>catch</literal> will produce errors even if the user
316 code has included libstdc++ headers and is using constructs
317 like <classname>basic_iostream</classname>. Even though the standard
318 library has been transformed, user code may need modification. User
319  code that attempts or expects to do error checking on standard
320  library components compiled with exception handling disabled should
321  be evaluated and potentially made conditional.
322</para>
323
324<para>
325  Some issues remain with this approach (see bugzilla entry
326  25191). Code paths are not equivalent, in
327  particular <literal>catch</literal> blocks are not evaluated. Also
328  problematic are <literal>throw</literal> expressions expecting a
329  user-defined throw handler. Known problem areas in the standard
330  library include using an instance
331  of <classname>basic_istream</classname>
332  with <function>exceptions</function> set to specific
333  <type>ios_base::iostate</type> conditions, or
334  cascading <literal>catch</literal> blocks that dispatch error
335  handling or recovery efforts based on the type of exception object
336  thrown.
337</para>
338
339<para>
340  Oh, and by the way: none of this hackery is at all
341  special. (Although perhaps well-deserving of a raised eyebrow.)
342  Support continues to evolve and may change in the future. Similar
343  and even additional techniques are used in other C++ libraries and
344  compilers.
345</para>
346
347<para>
348 C++ hackers with a bent for language and control-flow purity have
349  been successfully consoled by grizzled C veterans lamenting the
350  substitution of the C language keyword
351  <literal>const</literal> with the uglified
352  doppelganger <literal>__const</literal>.
353</para>
354
355
356</sect2>
357
358<sect2 id="intro.using.exception.compat">
359<title>Compatibility</title>
360
361<sect3 id="using.exception.compat.c">
362<title>With <literal>C</literal></title>
363<para>
364  C language code that is expecting to interoperate with C++ should be
365  compiled with <literal>-fexceptions</literal>. This will make
366  debugging a C language function called as part of C++-induced stack
367  unwinding possible.
368</para>
369
370<para>
371  In particular, unwinding into a frame with no exception handling
372data will cause a runtime abort. If the unwinder runs out of unwind
373info before it finds a handler, <function>std::terminate()</function>
374is called.
375</para>
376
377<para>
378  Please note that most development environments should take care of
379  getting these details right. For GNU systems, all appropriate parts
380  of the GNU C library are already compiled
381  with <literal>-fexceptions</literal>.
382</para>
383
384</sect3>
385
386<sect3 id="using.exception.compat.posix">
387<title>With <literal>POSIX</literal> thread cancellation</title>
388
389<para>
390  GNU systems re-use some of the exception handling mechanisms to
391  track control flow for <literal>POSIX</literal> thread cancellation.
392</para>
393
394<para>
395  Cancellation points are functions defined by POSIX as worthy of
396  special treatment. The standard library may use some of these
397  functions to implement parts of the ISO C++ standard or depend on
398  them for extensions.
399</para>
400
401<para>
402  Of note:
403</para>
404
405<para>
406  <function>nanosleep</function>,
407  <function>read</function>, <function>write</function>, <function>open</function>, <function>close</function>,
408  and <function>wait</function>.
409</para>
410
411<para>
412  The parts of libstdc++ that use C library functions marked as
413  cancellation points should take pains to be exception neutral.
414  Failing this, <literal>catch</literal> blocks have been augmented to
415  show that the POSIX cancellation object is in flight.
416</para>
417
418<para>
419  This augmentation adds a <literal>catch</literal> block
420  for <classname>__cxxabiv1::__forced_unwind</classname>, which is the
421  object representing the POSIX cancellation object. Like so:
422</para>
423
424<programlisting>
425  catch(const __cxxabiv1::__forced_unwind&amp;)
426  {
427    this->_M_setstate(ios_base::badbit);
428    throw;
429  }
430  catch(...)
431  { this->_M_setstate(ios_base::badbit); }
432</programlisting>
433
434
435</sect3>
436</sect2>
437
438<bibliography id="using.exceptions.biblio">
439<title>Bibliography</title>
440
441  <biblioentry>
442    <biblioid class="uri">
443      <ulink url="http://www.opengroup.org/austin/">
444	<citetitle>
445	  System Interface Definitions, Issue 7 (IEEE Std. 1003.1-2008)
446	</citetitle>
447      </ulink>
448    </biblioid>
449    <pagenums>
450      2.9.5 Thread Cancellation
451    </pagenums>
452    <copyright>
453      <year>2008</year>
454      <holder>
455	The Open Group/The Institute of Electrical and Electronics
456	Engineers, Inc.
457      </holder>
458    </copyright>
459  </biblioentry>
460
461  <biblioentry>
462    <biblioid class="uri">
463      <ulink url="http://www.boost.org/community/error_handling.html">
464	<citetitle>
465	  Error and Exception Handling
466	</citetitle>
467      </ulink>
468    </biblioid>
469    <author>
470      <firstname>David</firstname>
471      <surname>Abrahams </surname>
472    </author>
473    <publisher>
474      <publishername>
475	Boost
476      </publishername>
477    </publisher>
478  </biblioentry>
479
480
481  <biblioentry>
482    <biblioid class="uri">
483      <ulink url="http://www.boost.org/community/exception_safety.html">
484	<citetitle>
485	  Exception-Safety in Generic Components
486	</citetitle>
487      </ulink>
488    </biblioid>
489    <author>
490      <firstname>David</firstname>
491      <surname>Abrahams</surname>
492    </author>
493    <publisher>
494      <publishername>
495	Boost
496      </publishername>
497    </publisher>
498  </biblioentry>
499
500  <biblioentry>
501    <biblioid class="uri">
502      <ulink url="www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1077.pdf">
503	<citetitle>
504	  Standard Library Exception Policy
505	</citetitle>
506      </ulink>
507    </biblioid>
508    <author>
509      <firstname>Matt</firstname>
510      <surname>Austern</surname>
511    </author>
512    <publisher>
513      <publishername>
514	WG21 N1077
515      </publishername>
516    </publisher>
517  </biblioentry>
518
519  <biblioentry>
520    <biblioid class="uri">
521      <ulink url="http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00661.html">
522	<citetitle>
523	  ia64 c++ abi exception handling
524	</citetitle>
525      </ulink>
526    </biblioid>
527    <author>
528      <firstname>Richard</firstname>
529      <surname>Henderson</surname>
530    </author>
531    <publisher>
532      <publishername>
533	GNU
534      </publishername>
535    </publisher>
536  </biblioentry>
537
538  <biblioentry>
539    <biblioid class="uri">
540      <ulink url="http://www.research.att.com/~bs/3rd_safe.pdf">
541	<citetitle>
542	  Appendix E: Standard-Library Exception Safety
543	</citetitle>
544      </ulink>
545    </biblioid>
546    <author>
547      <firstname>Bjarne</firstname>
548      <surname>Stroustrup</surname>
549    </author>
550  </biblioentry>
551
552  <biblioentry>
553    <title>
554      Exceptional C++
555    </title>
556    <pagenums>
557      Exception-Safety Issues and Techniques
558    </pagenums>
559    <author>
560      <firstname>Herb</firstname>
561      <surname>Sutter</surname>
562    </author>
563  </biblioentry>
564
565  <biblioentry>
566    <biblioid class="uri">
567      <ulink url="http://gcc.gnu.org/PR25191">
568	<citetitle>
569	  GCC Bug 25191: exception_defines.h #defines try/catch
570	</citetitle>
571      </ulink>
572    </biblioid>
573  </biblioentry>
574
575</bibliography>
576
577</sect1>
578