handling exceptions in c & c++[part a]
DESCRIPTION
First part of my series on Exception Handling. Talks mostly of the stuff in C. Prepared in 2007TRANSCRIPT
Oct 04, 2007
Handling Exceptions in C++
Dr. Partha Pratim DasInterra Systems (India) Pvt. Ltd.
PART APART A
04/11/23 22
Agenda
• PART A– Exception Fundamentals
– Exceptions in C• C Language Features
• C Standard Library Support
– SEH in Microsoft C
– Exceptions in C++• C++ Language Features
– try–catch–throw
– Exception Specifications
• C++ Standard Library Support
04/11/23 33
Agenda
• PART B– Exception Instrumentations in C++
• How Compilers Manage Exceptional Flow?
– Designing with Exceptions in C++• Goals
• Scope
• Anatomy of a Function
• Meyers Guidelines
04/11/23 44
Agenda
• PART C– Designing with Exceptions in C++
• Analysis & Design of an Exception-safe stack
• Exception behavior of Standard Library
• Handling Exceptions in Multithreaded Environment
• TR1 Proposal
04/11/23 55
PART APART A
04/11/23 66
Exception Fundamentals
Basic NotionsBasic Notions
04/11/23 77
An exceptional circumstance is not necessarily an error
• What is Exception?– Conditions that arise infrequently and unexpectedly,
generally betray a program error, and require a considered programmatic response.
• Runtime Error – yes, but not necessarily
• Consequence– May render the program crippled or dead, sometimes taking
the entire system down with it.
• Defensive Techniques– Often trades one problem (crashing exceptions) for another
(more tangled design and code).
04/11/23 88
I had thought through the design, but …
• Unexpected Systems State– Exhaustion of Resources
• Low Free store memory
• Low Disk Space
– Pushing to a full stack
• External Events– ^C– Socket Event
04/11/23 99
My program was correct, well tested, but for …
• Logical Errors– Pop from an empty stack– Resource Errors – UMR, NPR, NPW, FMR, FMW,
FMM, FNH, FUM, ABR, ABW, FIU, …• MLK, PLK are not exceptions
• Runtime Errors– Arithmetic Overflow / Underflow– Out of Range
04/11/23 1010
I managed to put the system out of gear …
• Undefined Operation– Division by 0
04/11/23 1111
Do I need Exception Handling?
• Exception handling is a mechanism that separates code that detects and handles exceptional circumstances from the rest of your program. – Normal Flow– Exceptional Flow
“Exceptions are C++s means of separating error reporting from error handling”– Bjarne
Stroustrup
04/11/23 1212
The Classical Dilemma
• Library can detect runtime errors but does not in general have any idea what to do about them.
• Application using a library may know how to cope with such errors but cannot detect them.
04/11/23 1313
Types of Exceptions• Asynchronous Exceptions:
– Exceptions that come unexpectedly– Example – an Interrupt in a program– Takes control away from the executing thread context
to a context that is different from that which caused the exception.
• Synchronous Exceptions: – Planned Exceptions – Handled in an organized manner. – The most common type of synchronous exception is
implemented as a "throw."
04/11/23 1414
Exception Stages• [1] Error Incidence
– Synchronous (S/W) Logical Error– Asynchronous (H/W) Interrupt S/W Interrupt
• [2] Create Object & Raise Exception– An Exception Object can be of any complete type– An int to a full blown C++ class object
• [3] Detect Exception – Polling – Software Tests– Notification – Control (Stack) Adjustments
04/11/23 1515
Exception Stages
• [4] Handle Exception– Ignore: hope someone else handles it.– Act: but allow others to handle it afterwards.– Own: take complete ownership.
04/11/23 1616
Exception Stages
• [5] Recover from Exception– Continue Execution: If handled inside the
program• Resuming Exceptions – PL/I, Eiffel (limited), VC++
(SEH) – From where the exception was generated.
• Terminating Exceptions – Ada, Modula, C++, Java– From where the exception was handled.
– Abort Execution: If handled outside the program
04/11/23 Handling Exceptions in C and C++, Part 1 (Deep C++) by Robert Schmidt
1717
Exception Stages
int f() {int error;/* ... */if (error) /* Stage 1: error occurred */
return -1; /* Stage 2: generate exception object *//* ... */
}
int main(void) {if (f() != 0) /* Stage 3: detect exception */{
/* Stage 4: handle exception */}/* Stage 5: recover */
}
04/11/23 1818
Exceptions in C
A Recap of Error Handling A Recap of Error Handling TechniquesTechniques
04/11/23 1919
Support for Exceptions in C• Language Feature
– Return Value & Parameters– Local goto
• Standard Library Support– Global Variables– Abnormal Termination– Conditional Termination– Non-Local goto– Signals
04/11/23 2020
Exceptions in C: Language Features
• Return Value & Parameters
• Local goto
04/11/23 2121
Exceptions in C: Return Value & Parameters
• Function Return Value Mechanism– Created by the Callee as Temporary Objects– Passed onto the Caller – Caller checks for Error Conditions
if ((p = malloc(n)) == NULL) /* ... */if ((c = getchar()) == EOF) /* ... */if (A *p = dynamic_cast<A*>(pObj))/* ... */else/* ... */
04/11/23 2222
Exceptions in C: Return Value & Parameters
• Function Return Value is good, because– Are accessible by exactly two parties
• the one generating the exception, and
• the one detecting it.
– Take on exactly one value.– Cannot have their names hidden by user
declarations.• As they are nameless
– Are typically thread-safe.
04/11/23 2323
Exceptions in C: Return Value & Parameters
• Stages – 2: Raise
• Incidence of Error causes the Error Value to be returned by the Function Call
– 3: Detect• Calling Function detects the Error Value and takes
necessary decisions
04/11/23 2424
Exceptions in C: Return Value & Parameters
• Example 1int Push(int i) {
if (top_ == size-1) // Incidencereturn 0; // Raise
elsestack_[++top_] = i;
return 1;}
int main() {int x;// ...if (!Push(x)) // Detect {
// Handling}// Recovery
}
04/11/23 2525
Exceptions in C: Return Value & Parameters
• Example 2– HRESULT (Windows) Type– Returned by COM functions / interface methods– Returned for success, warning, & error values. – Not really handles to anything;
• 32-bit values with several fields encoded in the value.
– Zero indicates success, and a non-zero result indicates failure.
04/11/23 2626
Exceptions in C: Return Value & Parameters
• Example 2– COM Interfaces Support IUnknown:: QueryInterface
to get a pointer to a specified interface on an object to which a client currently holds an interface pointer.• HRESULT IUnknown::QueryInterface(
REFIID iid,
void ** ppvObject );
– Return Value•S_OK if the interface is supported, •E_NOINTERFACE if not.
04/11/23 2727
Exceptions in C: Return Value & Parameters
• Function (output) Parameter Mechanism– Return values can be ignored and lost. – Outbound parameters are bound to arguments
• Compared to return values, parameters form a tighter coupling between a function and its caller.
– Outbound parameters, offer multiple logical return values.
– Return values are temporary• RV Lifetime limited to the function call
• Arguments have a lifetime beyond the function call.
04/11/23 2828
Exceptions in C: Local goto
• Local goto Mechanism– [Source]
• Escapes: Gets Control out of a Deep Nested Loop
– [Destination] • Refactors: Actions from Multiple Points of
Error Inception– Separates Error Handling Code from the rest
– Enhances Cleanup Code by Reuse
04/11/23 2929
Exceptions in C: Local goto
• Local goto is a group of C Features– goto Label;
• Escapes & Refactors
– break; & continue• Escapes
– default switch case• Refactors
04/11/23 3030
Exceptions in C: Local goto • Stages
– 2: Raise• When Error occurs jump to a Label at End of
Function
– 3: Detect• At the Target Label Set the Error Value and Do
Code Clean Up
04/11/23 3131
Exceptions in C: Local goto • Example
– _PHNDLR __cdecl signal(int signum,
_PHNDLR sigact)
– Return:• Success:
– Signal returns the previous value of the signal handling function (e.g., SIG_DFL, SIG_IGN, etc., or [function address]).
• Failure: – Signal returns -1 and errno is set to EINVAL. The error
return is generally taken on bogus input values.
04/11/23 3232
Exceptions in C: Local goto _PHNDLR __cdecl signal(int signum, _PHNDLR sigact){ // Lifted from VC98\CRT\SRC\WINSIG.C... /* Check for sigact support */ if ( (sigact == ...) ) goto sigreterror;
/* Not exceptions in the host OS. */ if ( (signum == ... ) { ... goto sigreterror; }
else { ... goto sigretok; }
/* Exceptions in the host OS. */ if ( (signum ...) ) goto sigreterror;...sigretok: return(oldsigact);
sigreterror: errno = EINVAL; return(SIG_ERR);}
04/11/23 3333
Exceptions in C: Standard Library• Global Variables
• Abnormal Termination
• Conditional Termination
• Non-Local goto
• Signals
04/11/23 3434
Exceptions in C: Global Variables • GV Mechanism
– Use a designated Global Error Variable– Set it on error– Poll / Check it for detection
04/11/23 3535
Exceptions in C: Global Variables • GV Mechanism in Standard Library
– <errno.h> / <cerrno> Header defines “errno” plus several values it can take• EDOM :: Domain Error• ERANGE :: Out of Range Error• EILSEQ :: Multi-Byte Sequence Error• 0 :: No Error
– Used within <math.h> & <stdio.h> functions. – errno is set to 0 at program start– errno needs to be cleared before error incidence
04/11/23 3636
Exceptions in C: Global Variables • Windows Mechanism
– <winbase.h> / <windows.h>– DWORD GetLastError(void);
• Retrieves the calling thread's last-error code value.
– void SetLastError( DWORD dwErrCode ); • Sets the last-error code for the calling thread.
04/11/23 3737
Exceptions in C: Global Variables • Stages
– 1: Incidence• Initialize “errno” number to 0 and call Library
routine
– 2: Raise• Library Routine sets “errno” to appropriate value
– 3: Detect• User Code interrogates “errno” values for match
with EDOM, ERANGE or EILSEQ
04/11/23 Handling Exceptions in C and C++, Part 1 (Deep C++) by Robert Schmidt
3838
Exceptions in C: Global Variables • Example 1
04/11/23 3939
Exceptions in C: Global Variables • Example 2: Windows SDK
– To create a window, use:•HWND CreateWindowEx(…);
– Return Value• If the function succeeds, the return value is a handle
to the new window.
• If the function fails, the return value is NULL. – To get extended error information, call GetLastError.
04/11/23 4040
Exceptions in C: Abnormal Termination
• Abnormal Termination Mechanism– Program Halting Functions provided by <stdlib.h> / <cstdlib> Header
– abort() • Catastrophic Program Failure
– exit() • Code Clean up via atexit() Registrations
– atexit() • Handlers called in reverse order of their Registrations
04/11/23 4141
Exceptions in C: Abnormal Termination
• abort() – Abnormal program termination. – Run-time diagnostic and self-destruction. – May or may not flush / close opened files or
remove temporary files.
• exit() – Civilized program termination. – Closes opened files and returning a status.– Calls handlers registered via atexit().
04/11/23 4242
Exceptions in C: Abnormal Termination
• Signature: int atexit(void (*pFunction)(void)); • Use atexit() to register a function with signature
void CallbackFunction(void);
• Registered functions called from Runtime after main() exits
• If multiple functions are registered, then the calls will made be in the reverse order of registration (LIFO)
• Used by:– Compiler for Local Static Objects– Application Programmer for function call beyond main()
04/11/23 4343
Exceptions in C: Abnormal Termination
• Stages – 4: Handle
• Functions to be called by atexit() are registered in reverse order
– 5: Recover• Clean Up done after exit() via the calling functions
registered at atexit()
04/11/23 Handling Exceptions in C and C++, Part 1 (Deep C++) by Robert Schmidt
4444
Exceptions in C: Abnormal Termination
• Example
04/11/23 4545
Exceptions in C: Conditional Termination
• Conditional Termination Mechanism– Diagnostic ASSERT macro defined in <assert.h> / <cassert> Header
– Assertions valid when NDEBUG macro is not defined (debug build is done)
– Assert calls internal function, reports the source file details and then Terminates
04/11/23 4646
Exceptions in C: Conditional Termination
• Stages – 3: Detect
• Evaluates a Pre-condition Check
– 4: Handle• Calls Internal Functions (eg, _assert())
– 5: Recover• Details the failed condition and then calls abort()
04/11/23 4747
Exceptions in C: Conditional Termination
• ASSERT Macro
#if defined NDEBUG#define ASSERT(condition) ((void) 0)#else#define ASSERT(condition) \_assert((condition), #condition, __FILE__, __LINE__)#endif
04/11/23 Handling Exceptions in C and C++, Part 1 (Deep C++) by Robert Schmidt
4848
Exceptions in C: Conditional Termination
• Example
04/11/23 ASSERT and VERIFY: http://www.developerfusion.co.uk/show/1719/7/
4949
Exceptions in C: Conditional Termination
• Why is ASSERT a macro?– Stringize operation on the Expression– Manifest constants: File Name & Line No
• Can the test in ASSERT have side effect?– No. As, ASSERT works in debug build alone
• What is a VERIFY macro?#if defined NDEBUG#define VERIFY(condition) (condition) /* Survives */#else#define VERIFY(condition) \_assert((condition), #condition, __FILE__, __LINE__)#endif
04/11/23 5050
Exceptions in C: Non-Local goto • Non-Local goto Mechanism
– setjmp() and longjmp() functions provided in <setjmp.h> Header along with collateral type jmp_buf
– setjmp(jmp_buf) • Sets the Jump point filling up the jmp_buf object
with the current program context
– longjmp(jmp_buf, int) • Effects a Jump to the context of the jmp_buf object• Control return to setjmp call last called on jmp_buf
04/11/23 5151
Exceptions in C: Non-Local goto• The Dynamics
void f() {A a;if (setjmp(jbuf) == 0){
B b;g();h();
}else {
cout << ex.what();
}
return;}
jmp_buf jbuf;
void g(){
A a;UsrExcp ex(“From g()”);
longjmp(jbuf, 1);
return;}
04/11/23 5252
Exceptions in C: Non-Local goto • Stages
– 2: Raise• setjmp saves the program context in (jmp_buf)
• On Error longjmp returns control to the saved context
• Provides an integer as the exception object
– 3: Detect• The User Code branches to proper handler on
Integer Exception object
04/11/23 Handling Exceptions in C and C++, Part 1 (Deep C++) by Robert Schmidt
5353
Exceptions in C: Non-Local goto • Example 1
04/11/23 5454
Exceptions in C: Non-Local goto • Example 2
– Write a safe Solver for Quadratic Equations with Integer Coefficients.
• The equation as ax2+bx+c = 0 where a, b and c are integers.
• Use the general formula for solving a quadratic equation.
• The solver is expected to work in an infinite loop - read coefficients and print solutions.
• Normal program termination is by ^C.
04/11/23 5555
Exceptions in C: Non-Local goto • Example 2
– The Exception conditions are:• Input Insanity.
– Incidence: a == b == 0.– Handling/Recovery: Take fresh inputs; proceed as normal.
• Linear Equation. – Incidence: a == 0, b != 0.– Handling/Recovery: Use a different solver function for the
linear case (-c/b). Branch to this function for solution.
• Complex Roots. – Incidence: Discriminant is negative. – Handling/Recovery: Graceful termination with an apology.
04/11/23 5656
Exceptions in C: Non-Local goto • Notes
– jmp_buf stores the Environment (Program Context) comprising SP, FP, PC and registers
– jmp_buf is system dependent– The size of a jmp_buf is (around 2000)
• 6 pointers on Pentium/Linux,
• 19 on Sparc/Solaris, and
• 84 on Alpha/Digital-Unix.
– On save, setjmp returns 0.
#define _JBLEN 9typedef struct { int _jb[_JBLEN + 1]; } jmp_buf[1];
04/11/23 5757
Exceptions in C: Non-Local goto • Notes
– longjmp loads saved Environment from jmp_buf and sets return value to int Exception Object.• longjmp never returns (cannot)• Control transfers back to setjmp
• Stack Cutting is performed
– jmp_buf gets bad once control leaves the function scope from where setjmp was called.
– Stack Cutting does not Finalize! (Cannot, actually)
04/11/23 5858
Exceptions in C: Signals • Signal Mechanism
– Header <signal.h> – raise()
• Sends a signal to the executing program.– signal()
• Registers interrupt signal handler. It returns the previous handler associated with the given signal.
– Converts h/w interrupts to s/w interrupts
04/11/23 5959
Exceptions in C: Typical Signals• SIGABRT
– Abnormal termination. The default action terminates the calling program with exit code 3.
• SIGFPE – Floating-point error, such as overflow, division by zero,
or invalid operation. The default action terminates the calling program.
• SIGILL – Illegal instruction. The default action terminates the
calling program.
04/11/23 6060
Exceptions in C: Typical Signals• SIGINT
– CTRL+C interrupt. The default action issues INT 23H.
• SIGSEGV – Illegal storage access. The default action terminates the
calling program.
• SIGTERM – Termination request sent to the program. The default
action terminates the calling program.
04/11/23 6161
Exceptions in C: Signals • Stages
– 1: Incidence• External event
• Hardware Interrupt
– 2: Raise• Signal / Software Interrupt created
– 3: Detect• Search of Registered Handler
• Invocation of Handler
04/11/23 6262
Exceptions in C: Signals • Stages
– 4: Handle• Terminate
• Synchronize with Main code
– 5: Recover• Termination
• Abort
04/11/23 6363
Exceptions in C: Signals • Example
// Use signal to attach a signal // handler to the abort routine #include <stdio.h> #include <stdlib.h> #include <signal.h> #include <tchar.h> void SignalHandler(int signal) {
printf("Application aborting...\n"); }
int main() { typedef void (*SignalHandlerPointer)(int); SignalHandlerPointer previousHandler; previousHandler = signal(SIGABRT, SignalHandler); abort();
}
04/11/23 6464
Exceptions in C: Shortcomings • Destructor-ignorant.
– Oblivious of C++ destructors. – abort(), exit() and longjmp() cannot release
local objects during termination or stack unwind.– Resources leak.
• Obtrusive. – Interrogating global objects or function -return
values leads to code clutter. – Programmers "forget" error checks.
04/11/23 6565
Exceptions in C: Shortcomings • Inflexible.
– Return value spoils normal function semantics– longjmp() "throws" only a single int. – errno and signal/raise manipulate a small set of
values with coarse resolution. – abort() and exit() always terminate the program. – assert() works only in debug program versions.
• Non-native. – Require library support outside the core language.
04/11/23 6666
SEH in Microsoft-C
Standard Exception Handling Standard Exception Handling – A Precursor to Exception – A Precursor to Exception
Handling in C++Handling in C++
04/11/23 6767
SEH in VC++• SEH – Structured Exception Handling• Exception Handling in Microsoft C / C++
– Keywords• __except• __finally• __leave• __try
– Supports both termination and resume semantics in recovery
– Precursor to Exception Handling in C++ & Java
04/11/23 6868
SEH in VC++• Extended Constructs
__try{...}__except(filter-expression ){...}
__try{...}__finally{...}
__try{...__leave;...}
04/11/23 6969
SEH in VC++• Example
int filter(void) {/* Stage 4 */
}int main(void) {
__try {if (some_error) /* Stage 1 */
RaiseException(...); /* Stage 2 *//* Stage 5 of resuming exception */
}__except(filter()) /* Stage 3 */ {
/* Stage 5 of terminating exception */}return 0;
}
04/11/23 7070
Exceptions in C++
Basic NotionsBasic Notions
04/11/23 7171
Exceptions in C++: Expectations
• Separate – Error-handling code from ordinary code– Raise Code from Handle Code
• Automatic Detection
• Exception propagation allows a high level of reuse of exception handling code
• Release local resources automatically
04/11/23 7272
Exceptions in C++: Example
#include <iostream> using namespace std; int main () {
try{ ...
throw20; // throw an exception...} catch(int e) {
cout << "Exception No. " << e << endl; }
return 0; }
04/11/23 7373
Exceptions in C++: try–catch–throw
• Basic Mechanism
void f() {A a;try {
B b;g();h();
}catch (UsrExcp& ex) {
cout << ex.what();
}
return;}
class UsrExcp: public exceptions {}
void g(){
A a;UsrExcp ex(“From g()”);
throw ex;
return;}
04/11/23 7474
try Block: Scope• try block
– indicates areas in the program that might throw exceptions we want to handle immediately.
• function try block – indicates that we want to detect exceptions in
the entire body of a function.void f() try {
throw E("Exception thrown in f()"); } catch (E& e) {
cout << e.error << endl; }
04/11/23 7575
try Block: Nested try Block• Nesting try blocks is semantically equivalent to
nested function calls each having a separate level of try block
• A try block can be nested within a catch block.
try { func1(); try {
func2(); } catch (spec_err) {
/* ... */ } func3();
} catch (type_err) { /* ... */
}
04/11/23 7676
catch Block: Arguments• Catch is the name of all handlers
– must immediately follow the try block – formal parameter of each handler must be unique– Formal parameter does not have to be a variable– Can be simply a type name to distinguish its
handler from others– A variable transfers information to the handler – Catching an Exception is like a function being
invoked.
04/11/23 7777
catch Block: Matching throw-catch
• Exact Match: – The catch argument type matches the type of the
thrown object. • No implicit conversion is allowed.
• Generalization / Specialization: – The catch argument is a public base class of the
thrown class object.
• Pointer: – Pointer types – convertible by standard conversion.
04/11/23 7878
catch Block: Matching throw-catch
• NOTE:– cv-qualification for catch needs to be as strong as
the cv-qualification for throw• If the type of the thrown object is const or volatile,
the catch argument must also be a const or volatile for a match to occur.
• However, a const, volatile, or reference type catch argument can match a non-constant, nonvolatile, or non-reference object type.
– A non-reference catch argument type matches a reference to an object of the same type.
04/11/23 7979
catch Block: Order of Catch• In the order of appearance with matching.
• Should the catch block of a base class precedes a catch block of a derived class:– Compiler issues a warning and continues– Unreachable code (derived class handler)
ignored.
• catch(...) block must be the last catch block because it catches all exceptions.
04/11/23 8080
catch Block: Order of Match• In case of no matching handler in the
current scope, the search continues to find a matching handler in a dynamically surrounding try block. – Stack Unwinds
• If eventually no handler is found, terminate() is called.
04/11/23 8181
throw Expression: Semantics• Indicate that program has encountered an
exception.
• Expression is treated the same way as– A function argument in a call or – the operand of a return statement.
04/11/23 8282
throw Expression: Semantics• Exception Context
– class Exception {};
• The Expression– Generate an Exception object to throw.
• throw Exception();
– Or, Copies an existing Exception object to throw.• Exception ex;• …• throw ex; // Exception(ex);
• Exception object is created on the Free Store.
04/11/23 8383
(re) throw: Semantics• Re-throw
– catch may pass on the exception after handling.
– Re-throw is not same as throwing again!
// Re-throwtry { ... }catch (Exception& ex) {
// Handle and...// Pass-onthrow; // No copy// No Destruction
}
// Throws againtry { ... }catch (Exception& ex) {
// Handle and...// Raise againthrow ex;// ex copied// ex destructed
}
04/11/23 8484
throw Expression: Semantics• For a UDT Expression:
– copy constructor and destructor must be accessible.
• The type of Expression cannot be– An incomplete type, or – A pointer to an incomplete type, except
• void* • const void* • volatile void* • const volatile void*
04/11/23 8585
Incomplete Type
• The void type
• Arrays of unknown size
• Arrays of elements that are of incomplete type
• Structure, union, or enumerations that have no definition
• Pointers to class types that are declared but not defined
• Classes that are declared but not defined
04/11/23 8686
Incomplete Type
• Except:– If an array size is specified by [*], indicating a
variable length array, the size is considered as having been specified, and the array type is then considered a complete type.
• Examples:– void *incomplete_ptr; – struct dimension linear;
/* no previous definition of dimension */
04/11/23 8787
Exceptions in C++: Exception Lifetime
• [1] Incidence:– The program or its library traps an error
condition
• [2] Raise– Throws an exception– Exception object created on the Free Store
• Constructor / Copy Constructor publicly needed
04/11/23 8888
Exceptions in C++: Exception Lifetime
• [3] Detection– Execution stops at the point of the exception – Search for an exception handler begins. – Call stack is unwound till an exception
declaration is found that is compatible with the exception object's static type
04/11/23 8989
Exceptions in C++: Exception Lifetime
• [4] Handle– The corresponding handler is entered
• [5] Recover– Once the (catch) handler finishes, execution
jumps to the point just beyond the enclosing try block.
– Exception object is destructed• Destructor is publicly needed
– Standard exceptions are always terminating.
04/11/23 9090
Exceptions in C++: Advantages
• Destructor-savvy. – Stack unwinds during a throw– Local-objects destructed in the proper order.
• Unobtrusive. – Exceptions are caught implicitly and
automatically. No clutter of error checks.
• Precise. – Nearly any object can be thrown & caught.– Programmer controls exception semantics.
04/11/23 9191
Exceptions in C++: Advantages
• Scalable. – Each function can have multiple try blocks. – Each try block can have a single handler or a
group of handlers. – Each handler can catch a single type, a group of
types, or all types.
04/11/23 9292
Exceptions in C++: Advantages
• Fault -tolerant. – Functions can specify the exception types to throw;
handlers can specify the exception types to catch. – Violation behavior of these specifications is
predictable and user-configurable.
• Native. – EH is part of the C++ language.
• Standard. – EH is available in all standard C++ compilers.
04/11/23 9393
Exception Specifications in C++
NotionsNotions
04/11/23 9494
Exception Specification: Notion
• Limits a function to throwing only a specified list of exceptions.
• Given at the signature of the function.• Acts as a guarantee to the function's caller.
04/11/23 9595
Exception Specification: Rules
• Allow specified exceptions (and its specialization). – void *operator new (size_t) throw(bad_alloc); // Will throw bad_alloc or its specialization
• No / Wildcard specification allows all exceptions. – void *operator new (size_t);
// can throw bad_alloc – This is in standard– void *operator new (size_t) throw(...);
// can throw bad_alloc – This is not in standard
• Empty specification does not allow any exceptions. – void *operator new (size_t) throw();
// does not throw – nothrow version
04/11/23 9696
Exception Specification: Rules
• Multiple Specifications are allowed. For– void translate()
throw (unknown_word, bad_grammar)
– translate() will only throw exception of • type unknown_word or • type bad_grammar or • any type derived from unknown_word or • any type derived from bad_grammar.
• Reasoning about Exception Specification follows rules similar to cv-qualification
04/11/23 9797
Exception Specification: Details• An exception specification may only appear at
the end of a function declarator of a – function, – pointer / reference to function, – pointer to member function declaration / definition.
• An exception specification is not part of a function's type.– Functions cannot be overloaded on Specification– Specification cannot appear in a typedef
04/11/23 9898
Exception Specification: Examples
• void f() throw(int); • void (*g)() throw(int); • void h(void i() throw(int)); • // typedef int (*j)() throw(int);
// This is an error.
04/11/23 9999
Exception Specification: Examples
• It is okay to throw A() – as specified.• It is okay to throw B() – specialization from A.• It is a violation to throw C()
class A { }; class B : public A { }; class C { }; void f(int i) throw (A) {
switch (i) { case 0: throw A(); case 1: throw B(); default: throw C();
} }
Will ViolateWill Violate
04/11/23 100100
Exception Specification: Examples
• It is okay to throw pA – as specified.• It is okay to throw pB – B* specialized from A*.• It is a violation to throw pC – C* is unrelated.
void g(int i) throw (A*) { A* pA = new A(); B* pB = new B(); C* pC = new C();
switch (i) { case 0: throw pA; case 1: throw pB; default: throw pC;
} }
Will ViolateWill Violate
04/11/23 101101
Exception Specification: Violation Handling
• For specification violation, – Compiler calls
• void unexpected(); // from Standard Library
– That in turn calls• void terminate(); // from Standard Library
– Which by default calls • abort()
• If bad_exception is listed in the exception specification, – unexpected() will throw an implementation-defined
object of this class instead.
04/11/23 102102
Exception Specification: Violation Handling
• For specification violation, compiler calls (from Standard Library)– void unexpected(); – unexpected() may throw bad_exception;
• User can register her version of unexpected() by (Standard Library)– unexpected_handler set_unexpected(unexpected_handler) throw();
04/11/23 103103
Exception Specification: Polymorphism Restrictions
• A overriding virtual function can only throw exceptions specified by the virtual function in the base.
class A { public: virtual void f() throw(int, char); }; class B : public A { public: void f() throw(int) { } };
/* The following is not allowed. class C : public A { public: void f() throw(...) { } }; class D : public A { public: void f() throw(int, char, double) { } }; */
04/11/23 104104
Exception Specification: Function Pointer Restrictions
• f = h is allowed– f can throw any kind of exception.
• h = g is not allowed– h can only throw objects of type int, while g
can throw any kind of exception.
void (*f)(); void (*g)(); void (*h)() throw (int); void i() {
f = h; // h = g; This is an error.
}
04/11/23 105105
Exception Specification: Union of Specification
• C::C() can throw exceptions of type int or char. • C::C(C&) can throw any kind of exception. • C::~C() cannot throw any exceptions.
class A { public: A() throw (int); A(const A&) throw (float); ~A() throw(); };
class B { public: B() throw (char); B(const A&); ~B() throw(); };
class C : public B, public A { };
// Special functions // Implicitly declared // Implicitly specified C::C() throw (int, char); C::C(const C&); C::~C() throw();
04/11/23 106106
Exception Specification: Compiler Support
• Not all compilers Support Exception Specification• For example, Visual C++ departs from the ANSI
Standard in its exception specifications behavior. – throw():
• The function does not throw an exception.
• It is the equivalent to using __declspec(nothrow).
– throw(...): • The function can throw an exception.
– throw(type): • The function can throw an exception of type type. However, in
Visual C++ .NET, this is interpreted as throw(...).
04/11/23 107107
Exception Specification: Compiler Workaround
is equivalent to
void SomeFunction() throw (E1, E2) { ... }
void SomeFunction()try { ... }catch (E1) { throw; }catch (E2) { throw; }catch (...) { std::unexpected(); }
04/11/23 108108
Standard Exceptions in C++
Classes, Types and FunctionsClasses, Types and Functions
04/11/23 More Effective C++: Item 12 109109
Standard C++ Exception-Object Types
04/11/23 110110
Standard Exceptions: Classes• Exceptions for Language Support
– Operators & Mechanisms• operator new
– bad_alloc: On allocation failure
• operator dynamic_cast– bad_cast: On failure to resolve a reference
• operator typeid– bad_typeid: On NULL pointer
• unexpected() functions– bad_exception: On mismatched specification
04/11/23 111111
Standard Exceptions: Classes• Exception Classes for Standard Library
– logic_errors • Internal program bugs
• Theoretically preventable
• Exceptions are:– invalid_argument
– length_error
– out_of_range
– domain_error
– ios_base::failure: On error or end-of-file by stream objects
04/11/23 112112
Standard Exceptions: Classes• Exception for Errors outside the Scope of a
Program– runtime_errors
• External to program's control
• Difficult to predict.
• Exceptions are:– range_error
– overflow_error
– underflow_error
04/11/23 113113
Standard Exceptions: Headers• <exception>
namespace std{
// classesclass bad_exception;class exception;
}
04/11/23 114114
Standard Exceptions: Headers• <stdexcept>
namespace std{
class logic_error; // : public exceptionclass domain_error; // : public logic_errorclass invalid_argument; // : public logic_errorclass length_error; // : public logic_errorclass out_of_range; // : public logic_error
class runtime_error; // : public exceptionclass range_error; // : public runtime_errorclass overflow_error; // : public runtime_errorclass underflow_error; // : public runtime_error
}
04/11/23 115115
Standard Exceptions: Types• typedef void (*terminate_handler)();– Function pointer type for a program termination
handler• typedef void (*unexpected_handler)();– Function pointer type for an unexpected
exception handler
04/11/23 116116
Standard Exceptions: Functions• void terminate()
– Called when an exception is raised while a previous exceptional condition is still being handled (reentrancy).
• void unexpected()– Called when a function throws an exception it
promised not to throw, in violation of its exception specification.
– May be replaced by a bad_exception object during the stack unwind.
04/11/23 117117
Standard Exceptions: Functions• bool uncaught_exception()
– returns true if an exception has been thrown but not caught, and false otherwise.
04/11/23 118118
Standard Exceptions: Functions• terminate_handler set_terminate(terminate_handler) throw();– Registers a user-defined termination handler
• unexpected_handler set_unexpected(unexpected_handler) throw();– Registers a user-defined unexpected exception
handler
04/11/23 119119
Standard Exceptions: Headers• <exception>
namespace std{
// typestypedef void (*terminate_handler)();typedef void (*unexpected_handler)();// functionsterminate_handler
set_terminate(terminate_handler) throw();unexpected_handler
set_unexpected(unexpected_handler) throw();void terminate();void unexpected();bool uncaught_exception();
}
04/11/23 120120
Handling Exceptions in C & C++
References & CreditsReferences & Credits
13-May-05 121121
References• Handling Exceptions: Part 1 – 4
– Robert Schmidt• Modern C++ Design: Generic Programming & Design Pattern Applied
– Andrei Alexandrescu• Exceptional C++ & More Exceptional C++
– Herb Sutter • Effective C++ & More Effective C++
– Scott Meyers• Standard Features Missing From VC++ 7.1. Part I: Exception
Specifications – Nemanja Trifunovic
http://www.codeproject.com/cpp/stdexceptionspec.asp • A Pragmatic Look at Exception Specifications
– http://www.gotw.ca/publications/mill22.htm
04/11/23 122122
Credits / Acknowledgements
04/11/23 123123
Thank You