- Overview
-
Table of Contents
- Special Member Functions: Constructors, Destructors, and the Assignment Operator
- Operator Overloading
- Memory Management
- Templates
- Namespaces
- Time and Date Library
- Streams
- Object-Oriented Programming and Design Principles
- The Standard Template Library (STL) and Generic Programming
-
Exception Handling
- Traditional Error-Handling Methods
- Exception-Handling Constructs
- Exception Specifications
- Exceptions During Construction and Destruction
- Advanced Exception-Handling Techniques
- Exceptions and Performance
- Misuses of Exception Handling
- Summary
- Informit Articles and Sample Chapters
- Online Resources
- Avoiding Exceptions
- Function Try Blocks
- Function Try Blocks FAQ
- Runtime Type Information (RTTI)
- Signal Processing
- Creating Persistent Objects
- Bit Fields
- New Cast Operators
- Environment Variables
- Variadic Functions
- Pointers to Functions
- Function Objects
- Pointers to Members
- Lock Files
- Design Patterns
- Dynamic Linking
- Tips and Techniques
- Five Things You Need to Know About C++11 Unions
- A Tour of C99
- A Tour of C1X
- C++0X: The New Face of Standard C++
- C++0x Concurrency
- The Reflecting Circle
- We Have Mail
- The Soapbox
- Numeric Types and Arithmetic
- Careers
- Locales and Internationalization
Function Try Blocks FAQ
Last updated Jan 1, 2003.
After reading the overview of function try blocks I received questions about the usefulness of the said feature. Some readers ask whether they can use function try blocks to catch construction exceptions of namespace-scope objects by placing a function try block after main(). Others ask about the use of function try blocks in destructors and regular functions. Find out all the answers here.
Question: I have a global object that might throw during construction. Can I use a function try block on main() to catch such an exception?
Answer: Namespace scope objects (a category that includes global objects) are conceptually constructed before main() starts. Let's look at an example:
C obj; //global object that might throw during construction
main()
try //is it allowed?
{
}
catch(exception &e)
{
// doesn't catch exceptions from obj's ctor or dtor
}
If an exception is thrown during the construction of obj, there is no way to handle that exception. Placing a function try block right after main() will not do. The C++ standard explicitly prohibits that. Even if it were allowed, the handler would have to re-throw the exception anyway.
For similar reasons, you cannot catch exceptions thrown from the destructor of obj using a function try block.
Question: Can I use a function try block to catch exceptions thrown from a destructor?
Answer: Generally speaking, destructors should not throw exceptions at all. Yet technically, a function try block can be used on destructors:
C::~C() try { } catch(exception &e) { // must re-throw }However, there is no way to get out of a destructor's function try block handler except by throwing a new exception or re-throwing the original exception that's been caught. Therefore, using function try blocks on destructors is less useful than it might seem.
Question: My constructor doesn't have a member initialization list but it might throw. Can I use a function try block in this case?
Answer: In the absence of member initializers, there's no reason for using a function try block. Consider:
C::C()
try //function try block
{
p = new char[TERABYTE];
}
catch(bad_alloc& )
{
cerr<<"allocation failure!";
//rethrow
}
Instead, you can handle any potential exceptions by using traditional exception handling inside the constructor body:
C::C()
{
try //traditional exception handling
{
p = new char[TERABYTE];
}
catch(bad_alloc& )
{
cerr<<"allocation failure!";
}
}
As an aside, if your constructor might throw you may want to reconsider a different design approach such as the two-phased construction idiom, whereby the constructor performs only essential and exception-free initialization operations such as zeroing data members, and a separate member function later performs additional initialization steps that might throw.
Question: Can I use a function try block to catch exceptions from an ordinary function?
Answer: Yes, you can. However, you always have a better choice, namely replacing the function try block with traditional exception handling. Consider:
void f()
try //function try block
{
}
catch(exception &e)
{
}
When dealing with regular functions, you always have the option of wrapping the exception handling code with braces, effectively transforming the function try block into a traditional try block:
void f()
{ //added
try
{
}
catch(exception &e)
{
}
}//added
The second problem with regular functions is that you can't return a value from a function try block handler. Therefore, if your function has a return value other than void, you can't use function try blocks at all:
int g() //error
try
{
...
}
catch(exception &e)
{
//can't return a value from a handler!
}
In Conclusion
Although theoretically function try blocks aren't confined to constructors with member initializers, they aren't useful in other contexts. In some cases, e.g., main(), the C++ standard prohibits the use of function try blocks. In other cases (destructors, regular functions) it's technically possible to use function try blocks but their usefulness is moot.
