Verwenden von Standard-Exceptions mit strukturierten Exceptions (C++)
Nach oben zu Strukturierte Exceptions unter Win32 (C++)
Bei der Verwendung von strukturierten Exceptions in C++-Programmen müssen Sie ein paar wesentliche Punkte beachten. Zuallererst: Obwohl C++Builder C++-Exceptions mit strukturierten Win32-Exceptions implementiert, sind C++-Exceptions für einen __except-Block transparent.
Einem try-Block kann entweder genau ein except-Block oder mindestens ein catch-Block folgen. Bei dem Versuch diese beiden Blöcke zu vermengen, wird ein Compiler-Fehler ausgelöst. Code, der diese beiden Exception-Typen behandeln muss, sollte einfach in zwei try-Blöcke verschachtelt werden:
try {
EXCEPTION_POINTERS *xp;
try {
func();
}
__except (xfilter(xp = GetExceptionInformation())) {
// ...
}
}
catch (...) {
// ...
}
Die Spezifikation throw() einer Funktion wirkt sich nicht auf das Verhalten eines Programms in Bezug auf eine Win32-Exception aus. Zudem wird eine unbehandelte Exception irgendwann vom Betriebssystem behandelt (wenn der Debugger sie nicht zuvor behandelt), nicht wie bei C++-Programmen, die terminate() aufrufen.
Jedes mit der Compiler-Option -xd
(per Vorgabe aktiviert) compilierte Modul ruft Destruktoren für alle Objekte mit dem Speicherklassen-Bezeichner auto
auf. Das Abwickeln des Stack wird vom ersten Auslösen der Exception bis zu dem Punkt durchgeführt, an dem die Exception abgefangen wird.
Beispiel für C-basierte Exceptions in einem C++-Programm
/* 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;
}