If the compiler encounters an exception in a try block, it will try each handler in order of appearance.
If a catch block for objects of a base class precedes a catch block for objects of a class derived from that base class, the compiler issues a warning and continues to compile the program despite the unreachable code in the derived class handler.
A catch block of the form catch(...) must be the last catch block following a try block or an error occurs. This placement ensures that the catch(...) block does not prevent more specific catch blocks from catching exceptions intended for them.
#include <iostream>
using namespace std;
class E {
public:
const char* error;
E(const char* arg) : error(arg) { };
};
class F : public E {
public:
F(const char* arg) : E(arg) { };
};
void f() {
try {
cout << "In try block of f()" << endl;
throw E("Class E exception");
}
catch (F& e) {
cout << "In handler of f()";
cout << e.error << endl;
}
};
int main() {
try {
cout << "In main" << endl;
f();
}
catch (E& e) {
cout << "In handler of main: ";
cout << e.error << endl;
};
cout << "Resume execution in main" << endl;
}
The following is the output of the above example: In main In try block of f() In handler of main: Class E exception Resume execution in mainIn function f(), the run time could not find a handler to handle the exception of type E thrown. The run time finds a matching handler in a dynamically surrounding try block: the try block in the main() function.
If the run time cannot find a matching handler in the program, it calls the terminate() function.