diff options
Diffstat (limited to 'libstdc++-v3/doc/xml/manual/using_exceptions.xml')
-rw-r--r-- | libstdc++-v3/doc/xml/manual/using_exceptions.xml | 548 |
1 files changed, 548 insertions, 0 deletions
diff --git a/libstdc++-v3/doc/xml/manual/using_exceptions.xml b/libstdc++-v3/doc/xml/manual/using_exceptions.xml new file mode 100644 index 000000000..0ced13442 --- /dev/null +++ b/libstdc++-v3/doc/xml/manual/using_exceptions.xml @@ -0,0 +1,548 @@ +<section xmlns="http://docbook.org/ns/docbook" version="5.0" + xml:id="manual.intro.using.exceptions" xreflabel="Using Exceptions"> +<?dbhtml filename="using_exceptions.html"?> + +<info><title>Exceptions</title> + <keywordset> + <keyword> + C++ + </keyword> + <keyword> + exception + </keyword> + <keyword> + error + </keyword> + <keyword> + exception neutrality + </keyword> + <keyword> + exception safety + </keyword> + <keyword> + exception propagation + </keyword> + <keyword> + -fno-exceptions + </keyword> + </keywordset> +</info> + +<para> +The C++ language provides language support for stack unwinding +with <literal>try</literal> and <literal>catch</literal> blocks and +the <literal>throw</literal> keyword. +</para> + +<para> +These are very powerful constructs, and require some thought when +applied to the standard library in order to yield components that work +efficiently while cleaning up resources when unexpectedly killed via +exceptional circumstances. +</para> + +<para> +Two general topics of discussion follow: +exception neutrality and exception safety. +</para> + + +<section xml:id="intro.using.exception.safety" xreflabel="Exception Safety"><info><title>Exception Safety</title></info> + + + <para> + What is exception-safe code? + </para> + + <para> + Will define this as reasonable and well-defined behavior by classes + and functions from the standard library when used by user-defined + classes and functions that are themselves exception safe. + </para> + + <para> + Please note that using exceptions in combination with templates + imposes an additional requirement for exception + safety. Instantiating types are required to have destructors that + do no throw. + </para> + + <para> + Using the layered approach from Abrahams, can classify library + components as providing set levels of safety. These will be called + exception guarantees, and can be divided into three categories. + </para> + +<itemizedlist> + + <listitem> + <para> + One. Don't throw. + </para> + <para> + As specified in 23.2.1 general container requirements. Applicable + to container and string classes. + </para> + <para> + Member + functions <function>erase</function>, <function>pop_back</function>, <function>pop_front</function>, <function>swap</function>, <function>clear</function>. And <type>iterator</type> + copy constructor and assignment operator. + </para> + </listitem> + + <listitem> + <para> + Two. Don't leak resources when exceptions are thrown. This is + also referred to as the <quote>basic</quote> exception safety guarantee. + </para> + + <para> + This applicable throughout the standard library. + </para> + </listitem> + + <listitem> + <para> + Three. Commit-or-rollback semantics. This is + referred to as <quote>strong</quote> exception safety guarantee. + </para> + + <para> + As specified in 23.2.1 general container requirements. Applicable + to container and string classes. + </para> + <para> + Member functions <function>insert</function> of a single + element, <function>push_back</function>, <function>push_front</function>, + and <function>rehash</function>. + </para> + + </listitem> +</itemizedlist> + +</section> + + +<section xml:id="intro.using.exception.propagating" xreflabel="Exceptions Neutrality"><info><title>Exception Neutrality</title></info> + + <para> + Simply put, once thrown an exception object should continue in + flight unless handled explicitly. In practice, this means + propagating exceptions should not be swallowed in + gratuitous <literal>catch(...)</literal> blocks. Instead, + matching <literal>try</literal> and <literal>catch</literal> + blocks should have specific catch handlers and allow un-handed + exception objects to propagate. If a + terminating <literal>catch(...)</literal> blocks exist then it + should end with a <literal>throw</literal> to re-throw the current + exception. + </para> + + <para> + Why do this? + </para> + + <para> + By allowing exception objects to propagate, a more flexible + approach to error handling is made possible (although not + required.) Instead of dealing with an error immediately, one can + allow the exception to propagate up until sufficient context is + available and the choice of exiting or retrying can be made in an + informed manner. + </para> + + <para> + Unfortunately, this tends to be more of a guideline than a strict + rule as applied to the standard library. As such, the following is + a list of known problem areas where exceptions are not propagated. + </para> + +<itemizedlist> + <listitem> + <para> + Input/Output + </para> + <para> + The destructor <function>ios_base::Init::~Init()</function> + swallows all exceptions from <function>flush</function> called on + all open streams at termination. + </para> + + <para> + All formatted input in <classname>basic_istream</classname> or + formatted output in <classname>basic_ostream</classname> can be + configured to swallow exceptions + when <function>exceptions</function> is set to + ignore <type>ios_base::badbit</type>. + </para> + + <para> + Functions that have been registered + with <function>ios_base::register_callback</function> swallow all + exceptions when called as part of a callback event. + </para> + + <para> + When closing the underlying + file, <function>basic_filebuf::close</function> will swallow + (non-cancellation) exceptions thrown and return <literal>NULL</literal>. + </para> + </listitem> + <listitem> + <para> + Thread + </para> + <para> + The constructors of <classname>thread</classname> that take a + callable function argument swallow all exceptions resulting from + executing the function argument. + </para> + </listitem> +</itemizedlist> + +</section> + +<section xml:id="intro.using.exception.no" xreflabel="-fno-exceptions"><info><title>Doing without</title></info> + + <para> + C++ is a language that strives to be as efficient as is possible + in delivering features. As such, considerable care is used by both + language implementer and designers to make sure unused features + not impose hidden or unexpected costs. The GNU system tries to be + as flexible and as configurable as possible. So, it should come as + no surprise that GNU C++ provides an optional language extension, + spelled <literal>-fno-exceptions</literal>, as a way to excise the + implicitly generated magic necessary to + support <literal>try</literal> and <literal>catch</literal> blocks + and thrown objects. (Language support + for <literal>-fno-exceptions</literal> is documented in the GNU + GCC <link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#Code-Gen-Options">manual</link>.) + </para> + + <para>Before detailing the library support + for <literal>-fno-exceptions</literal>, first a passing note on + the things lost when this flag is used: it will break exceptions + trying to pass through code compiled + with <literal>-fno-exceptions</literal> whether or not that code + has any <literal>try</literal> or <literal>catch</literal> + constructs. If you might have some code that throws, you shouldn't + use <literal>-fno-exceptions</literal>. If you have some code that + uses <literal>try</literal> or <literal>catch</literal>, you + shouldn't use <literal>-fno-exceptions</literal>. + </para> + + <para> + And what it to be gained, tinkering in the back alleys with a + language like this? Exception handling overhead can be measured + in the size of the executable binary, and varies with the + capabilities of the underlying operating system and specific + configuration of the C++ compiler. On recent hardware with GNU + system software of the same age, the combined code and data size + overhead for enabling exception handling is around 7%. Of course, + if code size is of singular concern than using the appropriate + optimizer setting with exception handling enabled + (ie, <literal>-Os -fexceptions</literal>) may save up to twice + that, and preserve error checking. + </para> + + <para> + So. Hell bent, we race down the slippery track, knowing the brakes + are a little soft and that the right front wheel has a tendency to + wobble at speed. Go on: detail the standard library support + for <literal>-fno-exceptions</literal>. + </para> + + <para> + In sum, valid C++ code with exception handling is transformed into + a dialect without exception handling. In detailed steps: all use + of the C++ + keywords <literal>try</literal>, <literal>catch</literal>, + and <literal>throw</literal> in the standard library have been + permanently replaced with the pre-processor controlled equivalents + spelled <literal>__try</literal>, <literal>__catch</literal>, + and <literal>__throw_exception_again</literal>. They are defined + as follows. + </para> + +<programlisting> +#ifdef __EXCEPTIONS +# define __try try +# define __catch(X) catch(X) +# define __throw_exception_again throw +#else +# define __try if (true) +# define __catch(X) if (false) +# define __throw_exception_again +#endif +</programlisting> + +<para> + In addition, for every object derived from + class <classname>exception</classname>, there exists a corresponding + function with C language linkage. An example: +</para> + +<programlisting> +#ifdef __EXCEPTIONS + void __throw_bad_exception(void) + { throw bad_exception(); } +#else + void __throw_bad_exception(void) + { abort(); } +#endif +</programlisting> + +<para> + The last language feature needing to be transformed + by <literal>-fno-exceptions</literal> is treatment of exception + specifications on member functions. Fortunately, the compiler deals + with this by ignoring exception specifications and so no alternate + source markup is needed. +</para> + +<para> + By using this combination of language re-specification by the + compiler, and the pre-processor tricks and the functional + indirection layer for thrown exception objects by the library, + libstdc++ files can be compiled + with <literal>-fno-exceptions</literal>. +</para> + +<para> + User code that uses C++ keywords + like <literal>throw</literal>, <literal>try</literal>, + and <literal>catch</literal> will produce errors even if the user + code has included libstdc++ headers and is using constructs + like <classname>basic_iostream</classname>. Even though the standard + library has been transformed, user code may need modification. User + code that attempts or expects to do error checking on standard + library components compiled with exception handling disabled should + be evaluated and potentially made conditional. +</para> + +<para> + Some issues remain with this approach (see bugzilla entry + 25191). Code paths are not equivalent, in + particular <literal>catch</literal> blocks are not evaluated. Also + problematic are <literal>throw</literal> expressions expecting a + user-defined throw handler. Known problem areas in the standard + library include using an instance + of <classname>basic_istream</classname> + with <function>exceptions</function> set to specific + <type>ios_base::iostate</type> conditions, or + cascading <literal>catch</literal> blocks that dispatch error + handling or recovery efforts based on the type of exception object + thrown. +</para> + +<para> + Oh, and by the way: none of this hackery is at all + special. (Although perhaps well-deserving of a raised eyebrow.) + Support continues to evolve and may change in the future. Similar + and even additional techniques are used in other C++ libraries and + compilers. +</para> + +<para> + C++ hackers with a bent for language and control-flow purity have + been successfully consoled by grizzled C veterans lamenting the + substitution of the C language keyword + <literal>const</literal> with the uglified + doppelganger <literal>__const</literal>. +</para> + + +</section> + +<section xml:id="intro.using.exception.compat"><info><title>Compatibility</title></info> + + +<section xml:id="using.exception.compat.c"><info><title>With <literal>C</literal></title></info> + +<para> + C language code that is expecting to interoperate with C++ should be + compiled with <literal>-fexceptions</literal>. This will make + debugging a C language function called as part of C++-induced stack + unwinding possible. +</para> + +<para> + In particular, unwinding into a frame with no exception handling +data will cause a runtime abort. If the unwinder runs out of unwind +info before it finds a handler, <function>std::terminate()</function> +is called. +</para> + +<para> + Please note that most development environments should take care of + getting these details right. For GNU systems, all appropriate parts + of the GNU C library are already compiled + with <literal>-fexceptions</literal>. +</para> + +</section> + +<section xml:id="using.exception.compat.posix"><info><title>With <literal>POSIX</literal> thread cancellation</title></info> + + +<para> + GNU systems re-use some of the exception handling mechanisms to + track control flow for <literal>POSIX</literal> thread cancellation. +</para> + +<para> + Cancellation points are functions defined by POSIX as worthy of + special treatment. The standard library may use some of these + functions to implement parts of the ISO C++ standard or depend on + them for extensions. +</para> + +<para> + Of note: +</para> + +<para> + <function>nanosleep</function>, + <function>read</function>, <function>write</function>, <function>open</function>, <function>close</function>, + and <function>wait</function>. +</para> + +<para> + The parts of libstdc++ that use C library functions marked as + cancellation points should take pains to be exception neutral. + Failing this, <literal>catch</literal> blocks have been augmented to + show that the POSIX cancellation object is in flight. +</para> + +<para> + This augmentation adds a <literal>catch</literal> block + for <classname>__cxxabiv1::__forced_unwind</classname>, which is the + object representing the POSIX cancellation object. Like so: +</para> + +<programlisting> + catch(const __cxxabiv1::__forced_unwind&) + { + this->_M_setstate(ios_base::badbit); + throw; + } + catch(...) + { this->_M_setstate(ios_base::badbit); } +</programlisting> + + +</section> +</section> + +<bibliography xml:id="using.exceptions.biblio"><info><title>Bibliography</title></info> + + + <biblioentry> + <biblioid xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.opengroup.org/austin/" class="uri"> + </biblioid> + <citetitle> + System Interface Definitions, Issue 7 (IEEE Std. 1003.1-2008) + </citetitle> + + <pagenums> + 2.9.5 Thread Cancellation + </pagenums> + <copyright> + <year>2008</year> + <holder> + The Open Group/The Institute of Electrical and Electronics + Engineers, Inc. + </holder> + </copyright> + </biblioentry> + + <biblioentry> + <biblioid xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.boost.org/community/error_handling.html" class="uri"> + </biblioid> + <citetitle> + Error and Exception Handling + </citetitle> + + <author><personname><firstname>David</firstname><surname>Abrahams </surname></personname></author> + <publisher> + <publishername> + Boost + </publishername> + </publisher> + </biblioentry> + + + <biblioentry> + <biblioid xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.boost.org/community/exception_safety.html" class="uri"> + </biblioid> + <citetitle> + Exception-Safety in Generic Components + </citetitle> + + <author><personname><firstname>David</firstname><surname>Abrahams</surname></personname></author> + <publisher> + <publishername> + Boost + </publishername> + </publisher> + </biblioentry> + + <biblioentry> + <biblioid xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="www.open-std.org/jtc1/sc22/wg21/docs/papers/1997/N1077.pdf" class="uri"> + </biblioid> + <citetitle> + Standard Library Exception Policy + </citetitle> + <author><personname><firstname>Matt</firstname><surname>Austern</surname></personname></author> + <publisher> + <publishername> + WG21 N1077 + </publishername> + </publisher> + </biblioentry> + + <biblioentry> + <biblioid xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/ml/gcc-patches/2001-03/msg00661.html" class="uri"> + </biblioid> + <citetitle> + ia64 c++ abi exception handling + </citetitle> + + <author><personname><firstname>Richard</firstname><surname>Henderson</surname></personname></author> + <publisher> + <publishername> + GNU + </publishername> + </publisher> + </biblioentry> + + <biblioentry> + <biblioid xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.research.att.com/~bs/3rd_safe.pdf" class="uri"> + </biblioid> + <citetitle> + Appendix E: Standard-Library Exception Safety + </citetitle> + <author><personname><firstname>Bjarne</firstname><surname>Stroustrup</surname></personname></author> + </biblioentry> + + <biblioentry> + <citetitle> + Exceptional C++ + </citetitle> + <pagenums> + Exception-Safety Issues and Techniques + </pagenums> + <author><personname><firstname>Herb</firstname><surname>Sutter</surname></personname></author> + </biblioentry> + + <biblioentry> + <biblioid xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://gcc.gnu.org/PR25191" class="uri"> + </biblioid> + <citetitle> + GCC Bug 25191: exception_defines.h #defines try/catch + </citetitle> + </biblioentry> + +</bibliography> + +</section> |