Mixing Standard Exceptions with Structured Exceptions (C++)
Go Up to Structured Exceptions Under Win32 (C++)
You need to be aware of a few issues when using structured exceptions in C++ programs. First, although C++Builder implements C++ exceptions with Win32 structured exceptions, C++ exceptions are transparent to an __except block.
A try block can be followed by either exactly one except block or at least one catch block. Attempting to mix the two causes a compiler error. Code that needs to handle both types of exceptions should simply be nested inside two try blocks:
try {
EXCEPTION_POINTERS *xp;
try {
func();
}
__except (xfilter(xp = GetExceptionInformation())) {
// ...
}
}
catch (...) {
// ...
}
A function's throw() specification does not affect the behavior of a program with regard to a Win32 exception. Also, an unhandled exception is eventually handled by the operating system (if a debugger doesn't handle it first), unlike a C++ program that calls terminate().
Any module compiled with the -xd
compiler option (on by default) will invoke destructors for all objects with auto storage. Stack unwinding occurs from the point where the exception is thrown to the point where the exception is caught.
C-based exceptions in C++ program example
/* Program results:
Another exception:
Caught a C-based exception.
Caught C++ exception: Hardware error: Divide by 0 :
C++ allows __finally too!
*/
#include <stdio.h>
#include <string.h>
#include <windows.h>
class Exception {
public:
Exception(char* s = "Unknown") {
what = strdup(s);
}
Exception(const Exception& e) {
what = strdup(e.what);
}
~Exception() {
delete[]what;
}
char* msg() const {
return what;
}
private:
char* what;
};
int main() {
float e, f, g;
try {
try {
f = 1.0;
g = 0.0;
try {
puts("Another exception:");
e = f / g;
}
__except (EXCEPTION_EXECUTE_HANDLER) {
puts("Caught a C-based exception.");
throw(Exception("Hardware error: Divide by 0"));
}
}
catch (const Exception& e) {
printf("Caught C++ Exception: %s :\n", e.msg());
}
}
__finally {
puts("C++ allows __finally too!");
}
return e;
}