This page contains my personal observations about exception handling in some C++ compilers. If you have things to add or correct, let me know! Thanx to Jobst Köhne for helpful discussions on the subject.
GNU g++ has a compiler option -fhandle-exceptions that seems to suggest that it can handle exceptions. Alas, the option only ensures that the exception-handling related constructs (with the keywords try, throw, and catch) are running through the compiler correctly. However, the "throw" statements are ignored, and consequently "catch" statements are never executed.
Nevertheless, the error variables are instantiated and destroyed upon throw, as the output of the program c++test.C shows.
Programs with exception-handling related constructs will not compile.
The compiler error reads
error(3639): support for exception handling is disabled
Under Solaris, g++ can handle exceptions, when the option -fhandle-exceptions is used: Look at the output of the program c++test.C.
There are still some imperfections, though. An exception class (derivederror in the example) derived from a superclass (error) should be caught when the superclass is mentioned in the catch statement. This is to avoid the necessity that the user has to give a comprehensive list of all possible error classes in the catch statement. By using virtual functions (like print in the example) it is still possible to get the more comprehensive information from the derived class.
However, derived exceptions are not correctly caught under the name of their superclass, but only when there is an exact match.
int main() { try{ // here comes the "real" main program // ... return 0; // All is well that ends well. } catch (...) { // something went wrong. Do nothing, but don't leave exception uncaught. return 1; // It didn't end well... } }
A somewhat unexpected feature of exception handling can also seen from the output of the test program:
Apparently the destructor of the thrown object is called before
the catch statement (namely during the stack unwinding).
No constructor is called for the caught object, nor a destructor.
Nevertheless the caught object contains the state of the thrown object
I have no idea how this might affect the program if the thrown object contains pointers. Virtual functions are not affected, because derived objects can only be caught by exact match anyway.
Under Solaris, CC can handle exceptions. No special options have to be given. Look at the output of the program c++test.C.
The derived error class in the example is caught correctly, and the correct virtual debug print function is called.
The compiler also warns about the (for a correctly woking compiler) superfluous catch statement for the derived exception after the base class exception:
[amrum] ~/www/c++ $ CC c++test.C -o c++test.CC.solaris4x_55 "c++test.C", line 80: Warning: Handler for a derived class placed after handler for its base class. 1 Warning(s) detected.
Here CC seems to have a problem. Without the catch statement, not evem the cout buffers are flushed, so that no output appears. But the user gets a meaningful error message from the shell:
[amrum] ~/www/c++ $ c++test.CC.solaris4x_55 Run-time exception error; current exception: derivederror No handler for exception. zsh: 9726 IOT instruction c++test.CC.solaris4x_55
For CC, also the call of destructors for thrown objects happens at the point where it is expected: Namely when the caught object goes out of scope.
The only compiler with a decent exception handling tested here is CC on Solaris. But at least such compilers do exist!