C++ Exceptions und Relevanz



  • Shade Of Mine schrieb:

    Als Teil eines Scherzes hoffe ich.

    Naja, eigentlich war ich schon der Meinung dass das ernst gemeint war. Hoffe ich zumindest weil ich jetzt schon mein Programm so aufgebaut habe (und bis jetzt gut damit fahre) 😃

    Shade Of Mine schrieb:

    Sowas würde ich einem Mitarbeiter bei mir nicht durchgehen lassen.

    Warum? Wenn man in der run-Methode sehr viele geschachtelte Unterfunktions-Aufrufe hat ist es doch extrem mühsam im Falle eines Abbruchs alles immer durchzureichen?

    Mit einer exception hat man dagegen eine saubere Lösung und kann sich inder Implementierung auf das wesentliche konzentrieren...



  • wenn man ein plugins system mit dlls baut, sollte man in c++ besser keine excpetions verwenden.



  • Ah, OK - für Thread Beenden ist das eine häßliche Möglichkeit die man gerne aus Bequemlichkeit verwendet. Da kann es OK sein. Es spart Code und das ist es oft Wert.



  • happystudent schrieb:

    Warum? Wenn man in der run-Methode sehr viele geschachtelte Unterfunktions-Aufrufe hat ist es doch extrem mühsam im Falle eines Abbruchs alles immer durchzureichen?

    Threads bricht man eigentlich nur ab, wenn man sie fuer spekulative Ausfuehrung braucht und sie inzwischen nicht mehr braucht. Dann frage ich sie aber ueblicherweise in der aeussersten Schleife ab und nicht so oft zwischendurch.
    Ansonsten sind exceptions in threads auch gefaehrlich, denn wenn man sich gerade in einer critical section befindet, wird zwar der lock_guard geschlossen, aber es koennen noch unvollendete Werte bestehen bleiben.



  • Marthog schrieb:

    Threads bricht man eigentlich nur ab, wenn man sie fuer spekulative Ausfuehrung braucht und sie inzwischen nicht mehr braucht.

    Und zwar immer so, dass sich ein Thread selbst beendet. Von außerhalb sollte er nur das Signal bekommen, dass er (bald) sterben soll. Einen Thread zu killen ist immer problematisch, da man nie weiß was er gerade macht.



  • Andromeda schrieb:

    Und zwar immer so, dass sich ein Thread selbst beendet. Von außerhalb sollte er nur das Signal bekommen, dass er (bald) sterben soll. Einen Thread zu killen ist immer problematisch, da man nie weiß was er gerade macht.

    Ich mein ja auch nicht von killen, die exception wird schon von dem thread selbst geschmissen.

    Shade Of Mine schrieb:

    Ah, OK - für Thread Beenden ist das eine häßliche Möglichkeit die man gerne aus Bequemlichkeit verwendet. Da kann es OK sein. Es spart Code und das ist es oft Wert.

    Ja, aber das Problem warum man das da macht ist ja eigentlich unabhängig von dem Thread-Zeug: Man will halt nicht manuell aus etlichen Unterfunktionen rausgehen sondern direkt, das meinte ich.

    Deswegen sehe ich exceptions halt auch nicht nur als Fehler-Behandlungs-Mechanismen - ein throw ist ja auch eigentlich überhaupt nicht an eine exception gebunden. Man kann schließlich auch beliebige Objekte werfen (die dann auch nicht mehr das Wort "Ausnahme" mit sich tragen).

    Das gleiche Problem kann ich ja auch ohne threads haben:

    struct tier
    {
        struct fressfeind_alarm {};
    
        void such_nach_essbarem()
        {
            if (fressfeind_in_sicht())
                throw fressfeind_alarm(); // lass alles stehn und liegen
        }
    
        void suche_essen()
        {
            geh_in_gefaehrliches_gebiet();
            such_nach_essbarem();
            geh_in_sicheres_gebiet();
            schlaf_ein_paar_stunden();
        }
    
        void mach_was() 
        {
            while (true) {
                try { 
                    suche_essen() 
                } 
                catch (fressfeind_alarm &) { 
                    lauf_weg(); 
                }
            }
        }
    };
    

    Hier will man ja auch nicht unbedingt durch alle Funktionen zurückschleusen dass alles abgebrochen werden soll. Im Gegenteil, mMn passt eine exception (bzw. ein throw) hier perfekt zu der Modellierung des Tagesablaufs.



  • happystudent schrieb:

    Ja, aber das Problem warum man das da macht ist ja eigentlich unabhängig von dem Thread-Zeug: Man will halt nicht manuell aus etlichen Unterfunktionen rausgehen sondern direkt, das meinte ich.

    Das sollte aber nicht vorkommen. Thread beenden ist so eine Ausnahme Sache da man einen Thread manchmal eben killen will. Aber Prinzipiell ist flowcontrol mit Exceptions richtig mies.

    Nicht nur weil es lahm hoch 3 ist sondern auch weil es schwer nachverfolgbar ist und korrektheit nur schwer nachweisbar ist.

    Im Gegenteil, mMn passt eine exception (bzw. ein throw) hier perfekt zu der Modellierung des Tagesablaufs.

    Nein, hier ist das Design unpassend.

    Hier brauchst du ein Signal/Event basierstes System. Denn du willst auf Events (Feind gesichtet, Futter gesichtet, Wetter hat sich geändert, Es ist Nacht geworden, Magen voll, etc.) reagieren und da sind Exception einfach eine schlechte Lösung.

    Deshalb bin ich auch gegen das Thread-Beispiel. Es ist Excpetion-Missbrauch. Manchmal muss man Sachen missbrauchen um unmengen an Code zu sparen, aber Missbrauch bleibt Missbrauch und bitte bloß nicht in andere Situationen übertragen.



  • happystudent schrieb:

    Ja, aber das Problem warum man das da macht ist ja eigentlich unabhängig von dem Thread-Zeug: Man will halt nicht manuell aus etlichen Unterfunktionen rausgehen sondern direkt, das meinte ich.

    Wie setjmp/longjmp, die gibt es schon seit den C-Tagen.
    C++-Exceptions eröffnen dem Programmierer einen alternativen Ausführungspfad. Sie sind im Grunde eine Untergruppe der Coroutines. Nur dass es keinen Rückweg ins bisherige Level (wie finally in Java) gibt.



  • Andromeda schrieb:

    Wie setjmp/longjmp, die gibt es schon seit den C-Tagen.

    Meiner Meinung nach ist setjmp/longjmp eins der schrecklichsten C-Features überhaupt. Das ist quasi der größere, noch hässlichere, Bruder von goto. Besonders toll ist wenn man setjmp/longjmp aus einem C++ Projekt heraus nutzen muss (libpng jemand?). Man muss quasi alle Objekte die einen eigenen Destruktur definieren weit von dem Ganzen fern halten weil diese sonst im Falle eines longjmp nicht richtig zerstört werden. RAII kann man mal total vergessen.



  • sebi707 schrieb:

    Andromeda schrieb:

    Wie setjmp/longjmp, die gibt es schon seit den C-Tagen.

    Meiner Meinung nach ist setjmp/longjmp eins der schrecklichsten C-Features überhaupt. Das ist quasi der größere, noch hässlichere, Bruder von goto.

    So ist es. 😃

    C ist für echte Männer.
    C++ ist für Hausfrauen.

    Ernsthaft: wer beides beherrscht, ist gut aufgestellt. Wer aber nur auf C++ setzt und dabei C verteufelt, hat den geraden Weg in die Verdammnis eingeschlagen.


  • Mod

    Ernsthaft: wer beides beherrscht, ist gut aufgestellt. Wer aber nur auf C++ setzt und dabei C verteufelt, hat den geraden Weg in die Verdammnis eingeschlagen.

    Quatsch.



  • Arcoth schrieb:

    Ernsthaft: wer beides beherrscht, ist gut aufgestellt. Wer aber nur auf C++ setzt und dabei C verteufelt, hat den geraden Weg in die Verdammnis eingeschlagen.

    Quatsch.

    QFT!!!


  • Mod

    A language that doesn't affect the way you think about programming is not worth knowing.

    Quatsch.



  • Arcoth schrieb:

    Ernsthaft: wer beides beherrscht, ist gut aufgestellt. Wer aber nur auf C++ setzt und dabei C verteufelt, hat den geraden Weg in die Verdammnis eingeschlagen.

    Quatsch.

    Das liegt vielleicht daran, dass viele C++-Apologeten gehaupten, C++ wäre ein besseres C.



  • Shade Of Mine schrieb:

    Nein, hier ist das Design unpassend.

    Hier brauchst du ein Signal/Event basierstes System. Denn du willst auf Events (Feind gesichtet, Futter gesichtet, Wetter hat sich geändert, Es ist Nacht geworden, Magen voll, etc.) reagieren und da sind Exception einfach eine schlechte Lösung.

    Ja, das Beispiel war auch nicht ganz optimal.

    Wenn man jetzt das halt nur in 1-2 Situationen hat, dann find ichs halt Overkill extra dafür ein ganzes Event-System in den Code zu integrieren, aber ist wohl Geschmacksache.



  • Shade Of Mine schrieb:

    Ah, OK - für Thread Beenden ist das eine häßliche Möglichkeit die man gerne aus Bequemlichkeit verwendet. Da kann es OK sein. Es spart Code und das ist es oft Wert.

    Ich weiss auch nicht was daran so besonders hässlich sein soll.

    Ich weiss nur was daran (in C++) etwas problematisch ist - nämlich dass man so eine "abort exception", ganz egal welchen Typ sie hat, einfach mit catch (...) fangen und ignorieren kann.
    Was ich aber eher als Problem von C++ sehe - in C# gibt es dieses Problem z.B. nicht.



  • sebi707 schrieb:

    Andromeda schrieb:

    Wie setjmp/longjmp, die gibt es schon seit den C-Tagen.

    Meiner Meinung nach ist setjmp/longjmp eins der schrecklichsten C-Features überhaupt... (libpng jemand?).

    Libpng nicht, aber IJG-jpeg, bei der es zwischen meinen verwendeten Bibliotheken einen Versionskonflikt gab (Qt hatte seine eigene Version mitgebracht und einkompiliert). Fehler bei Initialisierung wurde nicht bedacht (ohne setjmp), dann der longjmp ins Nirvana zurück. Schon lustig zu debuggen wenn der irgendwo in den tiefen des Programms in einem der knapp 40 Threads einen Nullpointer dereferenziert und ihm dabei der Stack-Pointer fehlt... kein Call Stack... Debugger sagt: WTF? Keine Ahnung wo das grad passiert ist. Viel Spass beim Raten 😃

    Finnegan



  • Arcoth schrieb:

    A language that doesn't affect the way you think about programming is not worth knowing.

    Quatsch.

    Und was ist daran Quatsch? Mal davon abgesehen dass "worth" prinzipiell etwas Subjektives ist.

    Weißt du eigentlich was QFT bedeutet?

    @hustbaer:

    Weil man höllisch aufpassen muss. Ein zu aggresives catch irgendwo killt dir den ganzen Mechanismus und ist quasi nicht auffindbar.

    Prinzipiell ist es ein goto und das hat eben gewisse Nachteile.


  • Mod

    Shade Of Mine schrieb:

    Und was ist daran Quatsch?

    Sprachen sind Werkzeuge. Dein Zitat sagt sich schön, aber ich kann nicht erkennen, warum die genannte Bedingung hinreichend sein soll.

    Weißt du eigentlich was QFT bedeutet?

    Ja



  • Shade Of Mine schrieb:

    Weil man höllisch aufpassen muss. Ein zu aggresives catch irgendwo killt dir den ganzen Mechanismus und ist quasi nicht auffindbar.

    Das geht aber nur mit einem catch(...) (der Typ des geworfenen Objekts ist schließlich weggekapselt und nicht sichtbar). Und wenn man nach einem catch(...) nicht re-throwt ist man ja wohl selbst schuld bzw. hat eh ganz andere Probleme.

    Shade Of Mine schrieb:

    Prinzipiell ist es ein goto und das hat eben gewisse Nachteile.

    Ich finde es ist eigentlich eher ein allgemeineres return , wobei das geworfene Objekt der Rückgabewert ist.


Anmelden zum Antworten