Sofort beenden?



  • hm mir ist eine idee gekommen:

    void end_the_program () {
    
        class ExtremeError {
        public:
            ~ExtremeError () { throw 0; }
        };
    
        throw ExtremeError ();
    }
    
    #include <iostream>
    int main () {
       try {
          end_the_program ();
       } catch(...) {}
    
       std::cout << "Programm wurde erfolgreich ausgeführt\n";
    }
    

    Dann muss man nur noch im Destruktor wenn nötig den terminate handler außer gefecht setzen 🙂



  • Hallo,
    was du da machst ist großer Käse. Insbesondere werden hier keine lokalen Objekte zerstört. Eine Exception wird by-value geworfen. Hier wird also eine Kopie des Exception-Objekts erzeugt. Diese wird im Zuge des Stack-Unwindings zerstört. Der Dtor wirft eine weitere Exception die selbigen verlässt -> terminate() -> Ende aus und vorbei.

    Da gibt es deutlich einfachere Alternativen zu. Z.B.

    assert(false);
    

    Entweder der Fehler ist derart kritisch, dass überhaupt kein sinnvolles Verhalten mehr möglich ist, dann beende das Programm und mach dir keinen Kopf um lokale Objekte.
    Oder, falls noch sinnvolles Handeln möglich ist, wirf eine Exception und überlasse es dem aufrufenden Code diese zu behandeln.

    [ Dieser Beitrag wurde am 07.06.2003 um 18:33 Uhr von HumeSikkins editiert. ]



  • Ich weiß, dass ich momentan in meiner "alles, was ich sage ist großer Käse"-Fase bin, aber ist sowas in der Richtung nicht ganz ok.

    class Exit_program {};
    
    voif foo () 
    {
       ...
       if (...)   
          throw Exit_program();
       ...
    }
    
    int main()
    {
       try {
          foo();
       }
       catch(Exit_program & bar)
       {
       }
    }
    


  • ähm ja. käse-phase...

    der code soll das programm auf jedenfall beenden. nix mit fangen. aus. ende. programmabsturz.
    also wenn es nun wirklich nicht möglich ist, die lokalen objekte alle sicher zu zerstören, dann ist assert(false); sicher das beste...



  • Ist die Funktion main abgelufen, so wird das Programm beendet. Da mein catch die letzte Anweisung ist, die in der Funktion main steht, wird nach dem Werfen eines Exit_program das Programm beendet. Und eine sichere Zerstörung der Objekte sollte auch kein Problem sein.



  • wenn ich aber keinen zugriff auf main hab bzw. ich nicht der entwickler davon bin geht das nicht.



  • dann mach doch

    class Exit_program {};
    
    voif foo () 
    {
       ...
       if (...)   
          throw Exit_program();
       ...
    }
    
    void bar ()
    {
       try {
          foo();
       }
       catch(Exit_program & quer)
       {
       }
       catch(...) 
       {
          throw;
       }
       exit(0);
    }
    

    Wobei bar die Funktion ist, die die anderen aufrufen dürfen und foo ist deine private Funktion.

    [ Dieser Beitrag wurde am 08.06.2003 um 13:34 Uhr von Helium editiert. ]



  • oder ein assert(false)



  • Der Unterschied ist, dass du einmal sagst, dass das Programm ordnungsgemäß beendet wurde (meine Variante) und die andere Variante sagt, dass das Programm einen Fehler hat. Außerdem hast du bei mir noch die Möglichkeit beliebige Aktionen im catch-Bereich durchzuführen, die vor dem Beenden gemacht werden sollen.



  • nur soll das nicht gemacht werden 😉



  • Wenn ich lese:

    Wie beendet ihr euer Programm aus einer x-belibigen Funktion heraus???

    Dann denke ich numal zuerst daran, dass er vor hat das Programm ordnungsgemäß zu beenden und nicht einen Absturz erzwingen will.

    Aber ich warte noch daruaf, dass HumeSikkins oder Volkrad ankommen und mir sagen, was alles an meiner lösung schlecht ist oder warum sie erst garnicht funktioniert. In letzter Zeit war das nämlich bei fast allem so, was ich geschriben habe.



  • Eine Runde Mitleid 🙄 😃

    ok nagut, wahrscheinlic hhab ich mich wie so oft missverständlich ausgedrückt



  • Aber ich warte noch daruaf, dass HumeSikkins oder Volkrad ankommen und mir sagen, was alles an meiner lösung schlecht ist oder warum sie erst garnicht funktioniert. In letzter Zeit war das nämlich bei fast allem so, was ich geschriben habe

    Ich werde nichts derartiges sagen, da deine Methode *exakt* die ist, die ich für den Fall, dass noch ein *sinnvolles* reagieren möglich ist, vorgeschlagen habe.

    Der OP wollte aber das Programm in einer *beliebigen* Funktion *geordnet* beenden. Und das ist durch das Werfen einer Exception *nicht möglich*. Denn entweder der Exception-Mechanismus läuft geordnet ab, dann endet dein Programm an einer anderen Stelle oder er läuft ungeordnet ab und dann gibt es keine Garantien bzgl. lokaler Objekte.

    Also: Deine Möglichkeit, für den Fall, dass eine beliebige Funktion nicht mehr weiter weiß, grundsätzlich aber noch ein sinnvolles Handeln möglich ist (und wenn es nur das Beenden an einer anderen Stelle ist).
    Und ein assert(false) oder exit(IRGEND_WAS) oder ähnliches (am Besten etwas, dass einen direkt in den Debugger beamt) im anderen Fall.

    [ Dieser Beitrag wurde am 08.06.2003 um 14:37 Uhr von HumeSikkins editiert. ]



  • Juchu!



  • Ich finde throw int/catch int flexibler. Oder hab ich nen Denkfehler?



  • Allgemein besitzt eine Exception vom Typ int (ähnlich wie eine Zeichenkette als Exception)natürlich keinerlei interessante Typinformationen. Man muss also extra noch eine Bedeutung hinzupacken.
    Etwa so:

    catch(int& i)
    {
    switch(i)
    {
    case 1: // Das bedeutet jetzt tot
    case 2: // das ist nicht ganz so schlimm. 
    case 3: // und das finde ich eigentlich sogar ganz witzig
    }
    }
    

    Ich persönlich bevorzuge deshalb immer Exceptionobjekte einer Exceptionhierarchie.

    In Ausnahmefällen oder wenn ich mal keine Lust habe #include <assert.h> zu tippen werfe ich auch mal einen int. Generell halte ich das aber für keine gute Angewohnheit.



  • Ich glaube, du weisst nicht, was ich meine:

    double foo() {
      if (x)
        throw 0;
      throw -1;
    }
    int main() {
      try {
        double x = foo();
        cout << x << endl;
      } catch (int i) {
        return i;
      }
    }
    

    und wieso man int & catchen sollte, weiß ich nicht.



  • damit du mehrere werte aus der funktion zurückgeben kannst?
    tozz :p 🙄



  • Ich glaube, du weisst nicht, was ich meine:

    Doch das denke ich schon. Ich ging davon aus, dass du genau das meinst, was du dann als Beispiel gepostet hast. Ich halte dein Beispiel nur in Ausnahmefällen (kleines Testprogramm usw.) für angemessenen Programmierstil. Im Zuge eines größeren Projekts würde ich deine Vorgehensweise für ungeeignet halten. Eine int-Exception sagt *nichts* über das aufgetretene Problem. Ich müsste also zusätzliche Kommentare schreiben, die a) zusätzlichen Wartungsaufwand bedeuten und b) gelesen werden müssen.

    und wieso man int & catchen sollte, weiß ich nicht

    Aus Gründen der Einheitlichkeit z.B. Ich fange Exceptions immer by-reference (-auf const), da ich so Probleme durch slicing-Vermeide und ich außerdem nur so das Exception-Objekt verändern kann. Der erste Punkt trifft zwar bei int nicht zu und der zweite Punkt dürfte bei int ebenfalls nicht sonderlich relevant bleiben, es bringt mir aber keinen Vorteil by-value zu fangen. Also wozu von der gewohnten Art und Weise abweichen?

    [ Dieser Beitrag wurde am 09.06.2003 um 13:10 Uhr von HumeSikkins editiert. ]


Anmelden zum Antworten