Syntactic sugar or a useful feature? More than just sweet sweet sugar baby! This little known feature is a nice way of wrapping an entire function in a try catch block. So instead of writing this:
1 2 3 4 5 6 7 8 9 10 11 |
void eat_it() { try { throw runtime_error("System error from eat_it()"); } catch(exception& e) { cout << "Swallowing: " << e.what() << endl; } } |
You can write this:
1 2 3 4 5 6 7 8 |
void eat_it_sugar() try { throw runtime_error("System error from eat_it_sugar()"); } catch(exception& e) { cout << "Swallowing: " << e.what() << endl; } |
The meaning of the two functions is identical. Notice here I’m swallowing the exception instead of propagating it out. I could call throw to re-throw it, or in both cases I could throw a different exception inside the catch block.
The caveat is with function try-catch blocks around constructors: they have to re-throw the same or different exception. If you don’t re-throw explicitly the compiler will do it for you. It is also useful for catching exceptions emitted during the initialization of member variables, and throwing something else (or re-throwing the same). Like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
struct P { P() { throw logic_error("Logic error from P::P()"); } }; struct Q { Q() try : m_P() { cout << "Never printed!" << endl; } catch(exception& e) { cout << "Inside Q::Q() caught: " << e.what() << endl; throw runtime_error("Runtime error from Q::Q()"); } P m_P; }; |
Complete listing (try_block.cpp):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include <iostream> #include <stdexcept> using namespace std; struct P { P() { throw logic_error("Logic error from P::P()"); } }; struct Q { Q() try : m_P() { cout << "Never printed!" << endl; } catch(exception& e) { cout << "Inside Q::Q() caught: " << e.what() << endl; throw runtime_error("Runtime error from Q::Q()"); } P m_P; }; void eat_it() { try { throw runtime_error("System error from eat_it()"); } catch(exception& e) { cout << "Swallowing: " << e.what() << endl; } } void eat_it_sugar() try { throw runtime_error("System error from eat_it_sugar()"); } catch(exception& e) { cout << "Swallowing: " << e.what() << endl; } int main() try { eat_it(); eat_it_sugar(); Q q; } catch(exception& e) { cout << "Inside main() caught: " << e.what() << endl; } |
Swallowing: System error from eat_it()
Program output.
Swallowing: System error from eat_it_sugar()
Inside Q::Q() caught: Logic error from P::P()
Inside main() caught: Runtime error from Q::Q()
One Reply to “Function try-catch blocks”