The University of Iowa
The College of Liberal Arts and Sciences
Department of Computer Science
Programming Languages and Tools:
CS:3210:0001
Lecture/Lab #18
Programming with C++
Error handling/exceptions, RAII
Warm up
-
How do we check if reading from a stream was successful?
-
How do we reset the state of the input stream?
Error handling options
- Throwing an exception
- Returning a value indicating failure
- Terminating the program
int read_with_error_checking(std::istream& in) {
int n;
if ( in >> n ) // check for errors
return n;
std::cout << "Error reading from stream\n";
return -1;
}
int main() {
std::cout << "Enter an integer: ";
int n = read_with_error_checking( std::cin );
if ( n != -1 )
std::cout << "You entered: " << n << "\n";
}
Throwing an exception
int read_with_error_checking(std::istream& in) {
int n;
if ( in >> n ) // check for errors
return n;
throw std::runtime_error("Error reading from stream");
}
- Exceptions are a control flow mechanism designed for more scalable handling of run-time errors
- "Throwing" an exception terminates the regular control flow and transfers the execution to a matching `catch` handler in the most recently entered try/catch statement
- Exiting of functions and destruction of the corresponding local variables in the process of handling an exception is called "stack unwinding"
Throwing an exception (cont.)
- If there is no matching try/catch block, the program is terminated
- It's recommended to catch exceptions by const reference
- Derived exceptions will match a base class catch clause
- The order of class catch clauses matters: If multiple matching catch handlers are present, the first matching handler is selected.
- You can rethrow the old or throw a new exception from the catch block.
When to throw an exception
- Rare errors / errors that should not be ignored (e.g. out of memory)
- An error that cannot be handled by an immediate caller (e.g. network outage)
- No suitable return path for errors codes are available (e.g. constructors).
- The code flow is made more complicated or expensive by a need to pass both a value and an error indicator back.
- When in doubt, prefer exceptions.
When to return an error code
- A failure is normal and expected (e.g. opening a file).
- An immediate caller can reasonably be expected to handle the failure.
Consider using std::optional if choosing this route.
When to terminate
- Unrecoverable errors (e.g. memory exhaustion)
"Resource acquisition is initialization"
In plain language, RAII simply means tying resource management to the object lifetime:
- Allocate/obtain resource in object ctor
- Deallocation/release resource in object dtor
... where a resource could be almost anything that needs to be explicitly managed: memory, file handles, process handles, network sockets, database connections, mutexes, locks, etc.
Programming with C++, Spring 2020, Lecture #18
By Aleksey Gurtovoy
Programming with C++, Spring 2020, Lecture #18
Error handling/exceptions, RAII
- 527