Frage

Ich erwartete A::~A() in diesem Programm aufgerufen werden, aber es ist nicht:

#include <iostream>

struct A {
  ~A() { std::cout << "~A()" << std::endl; }
};

void f() {
  A a;
  throw "spam";
}

int main() { f(); }

Allerdings, wenn ich letzte Zeile ändern

int main() try { f(); } catch (...) { throw; }

dann A::~A() ist genannt.

ich mit "Microsoft (R) 32-Bit-C / C ++ Optimizing Compiler Version 14.00.50727.762 für 80x86" von Visual Studio bin Kompilieren 2005. Befehlszeile ist cl /EHa my.cpp.

Sie Compiler wie immer Recht? Was sagt Norm zu diesem Thema?

War es hilfreich?

Lösung

Der Destruktor wird nicht genannt, weil terminate () für die nicht behandelte Ausnahme aufgerufen wird, bevor der Stapel abgewickelt wird.

Die spezifischen Details, was die C ++ Spezifikation sagt außerhalb meines Wissens, sondern eine Debug-Trace mit GDB und g ++ dies zu bestätigen scheint.

Nach dem Normentwurf Abschnitt 15.3 Punkt 9:

9 If no matching handler is found in a program, the function terminate()
  (_except.terminate_)  is  called.  Whether or not the stack is unwound
  before calling terminate() is implementation-defined.

Andere Tipps

C ++ Sprachspezifikation lautet: Der Prozess der aufgerufen wird Destruktoren für automatische Objekte aufgebaut auf dem Weg von einem try-Block zu einem Einwurf Ausdruck Aufruf „Stack Abwickeln.“ Ihr Original-Code enthält keine try-Block, weshalb Stack Abwickeln nicht geschieht.

Ich nahm zu, dass die Compiler generieren den Code nicht in Bezug auf „a“, da es nicht referenziert ist aber immer noch, es ist nicht das richtige Verhalten als das destructor etwas tut, das ausgeführt werden muß.

Also habe ich versucht, in VS2008 / VC9 (+ SP1), Debug und Release and ~ A aufgerufen wird, nachdem die Ausnahme ausgelöst wird, aus f bekommen (.) - das ist das richtige Verhalten, wenn ich mich nicht irre

Jetzt gerade habe ich versucht, mit VS2005 / vc8 (+ SP1) und es ist das gleiche Verhalten.

Ich benutzte Stützpunkte sicher sein. Ich habe gerade mit der Konsole überprüft und ich habe das auch „~ A“ -Meldung. Vielleicht haben Sie es falsch woanders?

Leider habe ich nicht eine Kopie der Standard auf mich.
Ich würde auf jeden Fall wie eine endgültige Antwort auf diese, so jemand mit Kopie des Standard will Kapitel und Vers teile auf, was geschieht:

Von meinem Verständnis terminate wird nur aufgerufen, genau dann, wenn:

  • Die Ausnahmebehandlung kann nicht einen Handler für eine geworfene Ausnahme finden.
    Im Folgenden werden spezifischere Fälle folgt aus:
    • Während Stack Abwickeln eine Ausnahme entgeht eine destructor.
    • Ein geworfener Ausdruck, eine Ausnahme entkommt den Konstruktor.
    • Eine Ausnahme entkommt den Konstruktor / Destruktor eines nicht lokalen statischen (dh global)
    • Eine Ausnahme entgeht eine Funktion mit atexit registriert ().
    • Eine Ausnahme entkommt main ()
  • Der Versuch, eine Ausnahme erneut auslösen, wenn keine Ausnahme zur Zeit ausbreitet.
  • Eine unerwartete Ausnahme entgeht eine Funktion mit Ausnahme Bezeich (über unerwartete)

Diese Frage ist einfach so Google ich hier meine Situation teilen.

Stellen Sie sicher, yor exeption keine Kreuz extern "C" Grenze oder verwenden MSVC Option / EHs (Enable C ++ exeptions = Ja mit Extern C-Funktionen (/ EHS))

Im zweiten Beispiel, das dtor genannt wird, wenn er verlässt den try {} -Block.

Im ersten Beispiel wird der dtor genannt wird, da das Programm heruntergefahren, nachdem die Funktion main () verließ --- durch die Zeit cout bereits zerstört worden sein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top