Presentation is loading. Please wait.

Presentation is loading. Please wait.

Exceptions.

Similar presentations


Presentation on theme: "Exceptions."— Presentation transcript:

1 Exceptions

2 ? Query What does printf( ) return?
When was the last time you checked it? What is a good approach to error handling?

3 Error Handling with Exceptions
Forces you to defend yourself Separates error handling code from the source of error The source detects, the client handles No relentless checking of return values scattered throughout the code Saves CPU cycles if no errors occur End user errors are the “exception”, not the rule

4 Catching an Exception One or more handlers follow a try block
considered in order of appearance An exception matches a handler if it is of a compatible type: Same type Derived type void* catches all pointers catch(…) catches anything Always place the most specific handlers first

5 Throwing an Exception The exception object travels back up the call chain Execution backtracks until a matching handler is found Something very useful happens along the way…

6 Stack Unwinding As execution backtracks to a matching exception handler, the runtime stack is “unwound” The destructors for all local objects execute “Deterministic destruction” Example: C01/Cleanup.cpp

7 A Curiosity The statement throw Foo( ) creates a temporary Foo object in its scope How is that object eventually made available in the scope of the handler?

8 Exceptions are Copies A copy of the exception object is made
Exception types must have an accessible copy constructor If you catch by value, another copy is made Therefore: always catch exceptions by reference! Never throw pointers. How will the user know if it needs to be deleted? Who owns it?

9 How does all this really work?
throw is conceptually like a function call The “function called” is the handler it finally lands on Which takes the exception object as a “parameter” This runtime mechanism backtracks up the program stack (the “call chain”) Reading information placed there by each function activation If no matching handler is found in a function being visited, local objects’ are destroyed and the search continues Continues until a matching handler is found, or terminate is called.

10 Space Overhead Stats on next slide
struct C { ~C(){} }; void g(); // for all we know, g may throw void f() C c; // Destructor must be called g(); } If we hadn’t explicitly put a destructor in C, the compiler would have would have known that it didn’t need to generate code to destroy c, and there would have been no overhead.

11 Compiler Exception Support
Microsoft Visual C (omit option -EH) 654 bytes vs bytes g (option: -fno-exceptions) 932 bytes vs bytes

12 Uncaught Exceptions If no matching handler exists for an exception, the program terminates Actually, std::terminate( ) is called Which calls abort() You can override this behavior But you should still terminate the program Maybe log a message first, close connections, etc. Always try to avoid uncaught exceptions! Example: C01/Terminator.cpp

13 Resource Management When an exception occurs you want to guard against resource leaks Use RAII! Example: C01/Wrapped.cpp

14 Standard Exceptions Two Conceptual Categories
std::runtime_error For unforeseen errors std::logic_error For careless programmer errors Both declared in <stdexcept> Both derive from std::exception Declared in <exception> Example: C01/StdExcept.cpp Derive our exceptions from these categories, directly or indirectly.

15 What’s Wrong Here? void StackOfInt::grow() { // (Fields are capacity and data) // Enlarge stack’s data store capacity += INCREMENT; int* newData = new int[capacity]; for (size_t i = 0; i < count; ++i) newData[i] = data[i]; delete [] data; data = newData; }

16 An Improvement void StackOfInt::grow() { // Allocate a larger data store size_t newCapacity = capacity + INCREMENT; int* newData = new int[newCapacity]; for (size_t i = 0; i < count; ++i) newData[i] = data[i]; // Update state only when "safe" to do so delete [] data; data = newData; capacity = newCapacity; }

17 Fundamental Principle of Exception Safety
Separate operations that may throw from those that change state Only change state when no exceptions can occur Corollary: Do one thing at a time (cohesion) This is why std::stack<T>::pop( ) returns void The returned copy might throw during construction the object would be lost!

18 Rules of Exception Safety
If you can’t handle an exception, let it propagate up “Exception neutral” Leave your data in a consistent state Use RAII to allocate resources Only change your state with non-throwing ops An object should only own one resource Functions should perform only one logical operation Destructors should never throw


Download ppt "Exceptions."

Similar presentations


Ads by Google