Verwenden von Standard-Exceptions mit strukturierten Exceptions (C++)

Aus RAD Studio
Wechseln zu: Navigation, Suche

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;
 }

Siehe auch