Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C++

Function try-catch Blocks

0.00/5 (No votes)
2 Apr 2019MIT 2.6K  
Function try-catch blocks

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

C++
try
C++
catch

block. So instead of writing this:

C++
void eat_it()
{
	try
	{
		throw runtime_error("System error from eat_it()");
	}
	catch(exception& e)
	{
		cout << "Swallowing: " << e.what() << endl;
	}
}

You can write this:

C++
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 that I’m swallowing the exception instead of propagating it out. I could call...

C++
throw

...to re-throw it, or in both cases, I could throw a different exception inside the...

C++
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:

C++
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):

C++
#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;
}

Program output:

Swallowing: System error from eat_it()
Swallowing: System error from eat_it_sugar()
Inside Q::Q() caught: Logic error from P::P()
Inside main() caught: Runtime error from Q::Q()

License

This article, along with any associated source code and files, is licensed under The MIT License