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