C++0x checked exceptions?



  • Seh ich das richtig, dass es mit C++0x immer noch keine checked exceptions gibt?



  • Was meinst Du mit „immer noch“?



  • exceptionalcoder schrieb:

    Seh ich das richtig, dass es mit C++0x immer noch keine checked exceptions gibt?

    Konrad Rudolph schrieb:

    Was meinst Du mit „immer noch“?

    Ich rate jetzt mal einfach ins Blaue:

    Seh ich das richtig, dass es mit C++0x trotz über zehn Jahren Wartezeit keine checked exceptions gibt?



  • Gut, was meinst Du mit „trotz“? Was ist so tolles an Checked Exceptions?

    Oder anders ausgedrückt: Sehe ich das richtig, dass Ruby, Python, VB und C# allesamt, trotz über acht Jahren Wartezeit und diversen neuen Versionen, ebenfalls keine haben und sich niemand beklagt?

    Egal, ich wollte das eigentlich gar nicht so negativ ausdrücken. Vielleicht kann der OP ja mal erläutern, wieso er sie so sehr vermisst, denn ich persönlich empfinde sie in Java nicht als sonderlich nützlich.



  • Was ist denn das?



  • Man kann vernünftige Fehlerbehandlung mit checked Exceptions machen. Unchecked Exceptions sind genauso gefährlich wie Errorcodes als Rückgabewert, weil man sie einfach ignorieren kann. Dann crash halt plötzlich irgendwann das ganze Programm, weil man z.B. irgendwo keine Schreibrechte hat und trotzdem versucht zu schreiben und einfach mal davon ausgeht, dass es funktioniert und keine Fehlerbehandlung gemacht hat.



  • -. schrieb:

    Was ist denn das?

    checked exceptions sorgen dafür, dass code, der sich nicht um diese exceptions kümmert, nicht durch den compiler kommt.

    klassische c++ entwickler sind eher der auffassung, dass exceptions ihren sinn schon dann erfüllt haben, wenn ein stück code nicht mehr durchlaufen wird, sobald eine exception aufgetreten ist. primäraufgabe einer exception ist in diesem sinne also zu verhindern, dass in undefinierten zuständen munter weitergearbeitet wird.

    checked exceptions erfüllen eine ähnliche aufgabe, aber zusätzlich sollen sie einem entwickler aufzwingen, für exceptions eine fehlerbehandlung einzubauen. also z.b. anstatt bei einer I/O exception einfach blind auszusteigen, vorher noch wenigstens noch anständig aufzuräumen.

    checked exceptions kommen allerdings auch mit dem bittern beigeschmack, dass "faule" entwickler die dinger einfach abfangen, nichts tun, und trotzdem munter weiterrechnen. und schon ist man wieder im undefinierten zustand.



  • exceptionalcoder schrieb:

    Unchecked Exceptions sind genauso gefährlich wie Errorcodes als Rückgabewert, weil man sie einfach ignorieren kann.

    Ja, man kann. Das ist aber kein Argument. „You can write Fortran in any language.“
    Man kann auch Checked Exceptions einfach fangen und so tun, als wäre nichts gewesen – und das wird in Java übrigens extrem häufig genau so gemacht. Da hat man durch Checked Exceptions nichts gewonnen.



  • Konrad Rudolph schrieb:

    Man kann auch Checked Exceptions einfach fangen und so tun, als wäre nichts gewesen – und das wird in Java übrigens extrem häufig genau so gemacht. Da hat man durch Checked Exceptions nichts gewonnen.

    Man kann dadurch sogar noch größere Probleme bekommen, weil das Programm dann beim Testen nicht abstürzt und man dadurch eventuell nicht so leicht ermitteln kann, warum es sich falsch verhält.



  • Wenn ich mich richtig erinnere, muss man bestimmte Exceptions fangen. Aber dann gab es immer noch Exceptions, die man noch nicht einmal fangen darf. Errors oder so heißen die in Java. Ne, auf so ein System kann ich ehrlich gesagt verzichten.

    Da will ich lieber Lisp Conditions. Aber das dürfte ein bisschen schwierig sein in C++ zu implementieren ;).



  • Konrad Rudolph schrieb:

    exceptionalcoder schrieb:

    Unchecked Exceptions sind genauso gefährlich wie Errorcodes als Rückgabewert, weil man sie einfach ignorieren kann.

    Ja, man kann. Das ist aber kein Argument. „You can write Fortran in any language.“
    Man kann auch Checked Exceptions einfach fangen und so tun, als wäre nichts gewesen – und das wird in Java übrigens extrem häufig genau so gemacht. Da hat man durch Checked Exceptions nichts gewonnen.

    Es ist immerhin ein unterschied, ob man etwas absichtlich ignoriert oder einfach vergisst, weil man garnicht merkt, dass die methode eine Exception werfen kann. Und die leeren Excetions die du anscheinend so häufig in Java siehst werden eigentlich fast nur von Anfängern gemacht, weil sie nicht verstanden haben was das ganze soll.

    Kreppel schrieb:

    Konrad Rudolph schrieb:

    Man kann auch Checked Exceptions einfach fangen und so tun, als wäre nichts gewesen – und das wird in Java übrigens extrem häufig genau so gemacht. Da hat man durch Checked Exceptions nichts gewonnen.

    Man kann dadurch sogar noch größere Probleme bekommen, weil das Programm dann beim Testen nicht abstürzt und man dadurch eventuell nicht so leicht ermitteln kann, warum es sich falsch verhält.

    Leere catches die erst beim nächsten aufruf der Methode zu crashes führen hab ich auch schon mit den einfachen C++ exceptions gesehen. Also können wie jetzt alle Excetions weg werfen, weil man damit Mist bauen kann. 🙄

    rüdiger schrieb:

    Wenn ich mich richtig erinnere, muss man bestimmte Exceptions fangen. Aber dann gab es immer noch Exceptions, die man noch nicht einmal fangen darf. Errors oder so heißen die in Java. Ne, auf so ein System kann ich ehrlich gesagt verzichten.

    Errors sind keine Exceptions, das sind beides Throwables, schau dir mal die Vererbungshierarchie an. Und wieso sollte man Errors brauchen, wenn man checked Exceptions haben will?

    Was wäre den der große Nachteil wenn man Checked Exceptions in C++ hätte?



  • Checked Exceptions funktionieren in C++ nichtmal

    template<class Policy>
    class Foo
    {
        private:
            Policy policy;
        public:
            void do_something()
            {
                  //welche Exception wollen wir denn heute werfen?
                  policy.unknownCode();
            }
    };
    


  • otze schrieb:

    Checked Exceptions funktionieren in C++ nichtmal

    template<class Policy>
    class Foo
    {
        private:
            Policy policy;
        public:
            void do_something()
            {
                  //welche Exception wollen wir denn heute werfen?
                  policy.unknownCode();
            }
    };
    

    Was soll den da nicht funktionieren? Zum Kompilezeitpunkt steht fest, ob policy.unknownCode() eine checked Exception wirft oder nicht. Und so wie du es geschrieben hast, würdest du einen Compileerror bekommen, wenn policy.unknownCode() eine checked Exception werfen würde, weil du sie weder fängst noch weiter wirfst.



  • exceptionalcoder schrieb:

    Was soll den da nicht funktionieren? Zum Kompilezeitpunkt steht fest, ob policy.unknownCode() eine checked Exception wirft oder nicht. Und so wie du es geschrieben hast, würdest du einen Compileerror bekommen, wenn policy.unknownCode() eine checked Exception werfen würde, weil du sie weder fängst noch weiter wirfst.

    Und genau da liegt das Problem. Du musst nachträglich an Foo rumfummeln, um das zum laufen zu kriegen. Oder du musst von Anfang an festlegen, welche Exceptions eine Policy werfen darf und welche nicht. Das wäre dann Kristallkugelprogrammieren vom feinsten, und wiederspräche irgendwie dem Sinn der generischen programmierung.



  • Was hat den das mit "Kristallkugelprogrammieren" zu tun? Du legst doch schon fest, dass Policy eine Methode unknownCode() ohne Parameter haben muss. Was ist da jetzt anders zu dem, dass du noch zusätzlich festlegen würdest, dass diese Methode keine checked Exceptions werfen darf?

    Außerdem könnte man ja den Exceptiontyp den do_something weiter wirft oder fängt auch per Template festlegen, falls man das will.



  • Ich weiß gar nicht, wo dein Problem ist. Wenn eine Exception geworfen wird heißt das, dass irgendwas mächtig schiefgelaufen ist und wenn ich nicht weiß, wie ich damit umzugehen habe (<=> ich hab keinen entsprechenden Exceptionhandler implementiert) dann hat das Programm auch gefälligst zu sterben.

    exceptionalcoder schrieb:

    Was hat den das mit "Kristallkugelprogrammieren" zu tun? Du legst doch schon fest, dass Policy eine Methode unknownCode() ohne Parameter haben muss. Was ist da jetzt anders zu dem, dass du noch zusätzlich festlegen würdest, dass diese Methode keine checked Exceptions werfen darf?

    Und welche soll/darf die Funktion werfen? Die eine Policy implementiert Netzwerkstreams, die andere Dateistreams. Die erste wird vermutlich zwischendurch ein „Aye, Host 'blubb' antwortet nicht“ werfen wollen, die zweite „Aye, Datei 'bla' nicht gefunden“. Wenn beide nur CouldNotOpenStream("blubb"/"bla") werfen dürfen hast du einen signifikanten Informationsverlust, du kannst insbesondere keinen sinnvollen Handler implementieren (im ersten Fall eine Hostliste weiter durchgehen oder eine andere Schnittstelle benutzen, im zweiten anderen Pfad ausprobieren).



  • Ist es nicht mittlerweile auch im Java-Lager Konsens, dass Checked Exceptions vielleicht doch nicht so eine gute Idee sins, wie es zuerst schien? Mir war so. Wenn das einer sagt, klingt es jedenfalls in der Regel nicht so, als würde eine großartige Kontroverse angesprochen.



  • Es funktioniert in beiden Fällen gleich.
    Jetzt

    class CouldNotOpenStreamException {
    public:
    	virtual ~CouldNotOpenStreamException() {};
    	virtual void ayeJeMiNe() = 0;
    };
    
    class AyeHostAntwortetNichtException : public CouldNotOpenStreamException {
    public:
    	virtual ~AyeHostAntwortetNichtException() {};
    	virtual void ayeJeMiNe(){std::cout << "Au";};
    	void ayeHost(){std::cout << "Host blaa";};
    };
    
    class AyeDateiNichtGefundenException : public CouldNotOpenStreamException {
    public:
    	virtual ~AyeDateiNichtGefundenException() {};
    	virtual void ayeJeMiNe(){std::cout << "File blubberbla";};
    };
    
    class Policy1 {
    public:
    	void unknownCode() {
    		throw AyeHostAntwortetNichtException();
    	}
    };
    
    int main ()
    {   
    	try {
    		Policy1 p1;
    		p1.unknownCode();
    	} catch (AyeHostAntwortetNichtException &e) {
    		e.ayeHost();
    	} catch (CouldNotOpenStreamException &e) {
    		e.ayeJeMiNe();
    	}
    	Policy1 p1;
    	p1.unknownCode();  // möglicher Crash
    }
    

    Mögliche Variante mit Checked Exceptions

    class CouldNotOpenStreamException {
    public:
    	virtual ~CouldNotOpenStreamException() {};
    	virtual void ayeJeMiNe() = 0;
    };
    
    class AyeHostAntwortetNichtException : public CouldNotOpenStreamException {
    public:
    	virtual ~AyeHostAntwortetNichtException() {};
    	virtual void ayeJeMiNe(){std::cout << "Au";};
    	void ayeHost(){std::cout << "Host blaa";};
    };
    
    class AyeDateiNichtGefundenException : public CouldNotOpenStreamException {
    public:
    	virtual ~AyeDateiNichtGefundenException() {};
    	virtual void ayeJeMiNe(){std::cout << "File blubberbla";};
    };
    
    class Policy1 {
    public:
    	void unknownCode() throwsChecked[CouldNotOpenStreamException] {
    		throw AyeHostAntwortetNichtException();
    	}
    };
    
    int main ()
    {   
    	try {
    		Policy1 p1;
    		p1.unknownCode();
    	} catch (AyeHostAntwortetNichtException &e) {
    		e.ayeHost();
    	} catch (CouldNotOpenStreamException &e) {
    		e.ayeJeMiNe();
    	}
    	Policy1 p1;
    	p1.unknownCode();  // compiler error
    }
    

    Und was wäre jetzt an throwChecked so schlimm (außer meiner Syntax)? Es wäre einfach nur ein Hinweis für den Compiler, dass er eine Fehlermeldung ausgibt, wenn man die Exception nicht fängt. Ich hab hier bis jetzt noch kein richtiges Argument gegen checked Exceptions gehört, sondern immer nur konstruierte Probleme, die nicht wirklich welche sind.



  • Bashar schrieb:

    Ist es nicht mittlerweile auch im Java-Lager Konsens, dass Checked Exceptions vielleicht doch nicht so eine gute Idee sins, wie es zuerst schien? Mir war so. Wenn das einer sagt, klingt es jedenfalls in der Regel nicht so, als würde eine großartige Kontroverse angesprochen.

    Ja, Checked Exceptions sind out. Viele Frameworks und APIs benutzen mittlerweile vorwiegend RuntimeExceptions (Hibernate ist beispielsweise vor Jahren schon umgestiegen, früher war da auch alles "checked").
    Die Nachteile überwiegen einfach. Und im Zweifel kann der Entwickler besser entscheiden, ob eine Exception gefangen, ignoriert oder weitergeworfen werden muss, als der Designer der API oder des Frameworks. Warum sollte man also zu irgendwas gezwungen werden?


  • Administrator

    @exceptionalcoder,
    Du hast entweder keine Ahnung was templates sind oder solltest dir den Code von otze nochmals genauer anschauen.

    Ich bin übrigens auch gegen checked exceptions, aus den bereits genannten Gründen. In Java verwirrt es die Anfänger nur und später geht man die Wände hoch, wenn wegen jedem read oder write ein Fehler wegen einer IOException kommt. Und dann kann man die durch alle Funktionen durchgeben, bis zum GUI ... also throws throws throws throws throws throws ... argl

    Gegen eine Warnung oder eine Benachrichtigung hätte ich allerdings nichts dagegen, das wäre dagegen wirklich praktisch! Allerdings ist die Frage, wo und wie wird diese Benachrichtigung erzeugt. Wahrscheinlich schlussendlich zu viel Aufwand für zu wenig.

    Grüssli


Anmelden zum Antworten