- C++ Built-in Exception Handling Syntax
C++ provides native exception handling through the try-catch construct. The try block contains normal program logic, while catch blocks handle exceptional conditions. When an exception occurs with in a try block, it is processed by the corresponding catch handler.
Exceptions are thrown using the throw keyword, which generates exception information that propagates through the program.
- Exception Handling Behavior
When an exception is thrown via throw, it must be caught by a catch block, otherwise the program will terminate with an error.
- If the current function can handle the exception, execution continues after the catch block
- If the current function cannot handle the exception, the function stops and returns
- Unhandled exceptions propagate up the call stack until caught, otherwise the program terminates
The following example demonstrates exception handling for division operations:
#include <iostream>
using namespace std;
double divide(double numerator, double denominator)
{
const double epsilon = 0.000000000000001;
double result = 0;
if(!((-epsilon < denominator) && (denominator < epsilon)))
{
result = numerator / denominator;
}
else
{
throw 0; // Throw integer 0 when division by zero occurs
// Exception propagates to the calling function
}
return result;
}
int main()
{
try
{
// When divide throws an exception and it's not handled inside the function,
// the exception propagates to main() where the try-catch catches it.
// Execution transfers directly to the catch block, then continues to "return 0;".
// The line after the divide call is skipped.
double result = divide(1, 0);
cout << "result = " << result << endl;
}
catch(...)
{
cout << "Division by zero detected..." << endl;
}
return 0;
}
- Multiple Catch Blocks
A single try statement can be followed by multiple catch blocks, each handling a specific exception type. Different exception types are handled by their respective catch clauses.
- Each catch block specifies the exact type of exception it handles
- The try block can throw exceptions of any type
- The catch(...) syntax catches all exception types
- When multiple catch blocks are used, catch(...) must be placed last
- Each exception can only be caught once
- Expection Type Matching Rules
When an exception is thrown, the runtime searches catch handlers from top to bottom for a type match. During this matching process, no implicit type conversions are performed.
The example below illustrates strict type matching:
#include <iostream>
#include <string>
using namespace std;
void testIntException()
{
try
{
throw 1; // Integer type, will match catch(int)
// throw 'c' would match catch(char), no conversion occurs!
}
catch(char ch)
{
cout << "catch(char ch):" << ch << endl;
}
catch(short s)
{
cout << "catch(short s):" << s << endl;
}
catch(double d)
{
cout << "catch(double d):" << d << endl;
}
catch(int n)
{
cout << "catch(int n):" << n << endl;
}
catch(...)
{
cout << "catch(...)" << endl;
}
}
void testStringException()
{
throw "SantaClaus"; // const char* type
// throw string("SantaClaus"); // std::string type
}
int main()
{
testIntException();
try
{
testStringException();
}
catch(char* msg)
{
cout << "catch(char* msg):" << msg << endl;
}
catch(const char* msg)
{
cout << "catch(const char* msg):" << msg << endl;
}
catch(string msg)
{
cout << "catch(string msg):" << msg << endl;
}
return 0;
}
/* Output:
catch(int n):1
catch(const char* msg):SantaClaus
*/
Summary
- C++ provides native support for exception handling
- try-catch is the dedicated syntax for exception management in C++
- The try block contains normal execution logic, catch handles exceptional cases
- Multiple catch blocks can follow a single try statement
- Exception matching is strict with no type conversions performed