C++0x checked exceptions?
-
Exceptionist schrieb:
Selbst das Erzeugen einer Warnung kann bereits kontraproduktiv sein, da dann in größeren Anwendungen eine wahre Flut von Warnungen erzeugt werden würde und du sie ignorieren wirst oder relevante Warnungen in der Menge der unrelevanten gar nicht mehr finden wirst.
Checked Exceptions sind Käse, wenn ich Exceptions nicht fange schmiert mir im schlimmsten Fall die Anwendung ab, wenn ich sie Fange und nicht/falsch behandle kann alles mögliche passieren und kaum reproduzierbar sein.
das nennt man dann wohl "augen zu und durch", oder als marketing-buzzword vielleicht auch "ignorant programming". mit dem ersten argument kann man alle compilerwarnungen ganz abschaffen, und mit dem zweiten jede art von fehlerbehandlung.
es gibt üblicherweise warning-level, die man beim compiler einstellen kann. außerdem kann man idr einzelne warnungen gezielt abschalten.zum thema: checked exceptions können teilweise echt nerven, aber sie sind meiner meinung nach immer noch besser als der jetzige zustand in c++: jede funktion darf einfach alles werfen, ohne dass es irgendwo deklariert werden muss. vc++ (mind. 2003/2005) meckert sogar rum, wenn man nicht-leere exception specifications benutzen will.
wenn man weniger gut dokumentierte libs benutzt, darf man dann den (hoffentlich verfügbaren) quellcode lesen, wenn man alle exceptions gezielt berücksichtigen will.
-
In Ada wird im Vergleich zu anderen Programmiersprachen ziemlich viel vom Compiler erkannt. Checked Exceptions gibt es aber nicht.
Warum? Weil man in Verbindung mit Generics die geworfende Exception nicht immer vorhersehen kann. Man kann zwar auch unbekannte Exceptions fangen, aber mehr als eine Fehlerausgabe kann man daraus auch nicht generieren.
-
exceptionalcoder schrieb:
Ja ich merk was, dass du nix verstanden hast und dir dabei noch ganz toll vorkommst. Die Einschränkung mit der checked Exception ist nicht größer als die mit dem Namen und den Parametern. Hab ich ja bereits gesagt
Mal ganz ehrlich und ich möchte, dass du die Frage wirklich mal beantwortest. Hast du jemals schon in einem grösseren Projekt C++ Templates eingesetzt?
Denn mit dem hier:
exceptionalcoder schrieb:
... 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.schränkst du die templates wieder deutlich ein. Es ist nicht klar, ob eine Exception geworfen wird oder ob nicht, das ist es nie! Und es sollte auch nicht vorausgesetzt werden, auch nicht per zusätzlichen template parametern. Das macht die Sache höchstens unheimlich kompliziert oder schränkt die Templatefähigkeiten ungeheuer ein.
Zudem, wie so oft in C++ gilt halt das folgende:
Der Programmierer trägt die volle Verantwortung!Wenn du diese Verantwortung nicht willst, dann programmier halt in Java oder sonst einer Sprache, welche dir gefällt.
Grüssli
-
Kreppel schrieb:
Vielleicht wird die Situation mit den Policies klarer, wenn man ein Beispiel hat, das man direkt kompilieren und ausführen kann. Die Klasse Decision ist in diesem Beispiel der Host für die Policies, und es herrscht dort völlige Unklarheit über die Ausnahmen, die sich Policy-Autoren ausdenken (oder auch weglassen!) könnten:
#include <iostream> using namespace std; class FooPolicy { public: void do_something() { cout << "IMMA CHARGIN' MA LAZER!\n"; throw "SHOOP DA WOOOOOOOOOOOP!"; } }; class BarPolicy { public: void do_something() { cout << "Nothing dangerous here.\n"; } }; template<typename T> class Decision : public T { typedef T do_policy; public: void decide_something() { cout << "Let's see, what we do today...\n"; //Soll hier try/catch erzwungen werden oder nicht??? //Wenn jemand eine neue do_policy mit neuer Ausnahme schreibt, was dann??? do_policy::do_something(); } }; int main() { Decision<FooPolicy> df; Decision<BarPolicy> db; //Entscheidung mit FooPolicy ist gefährlich try { df.decide_something(); } catch (const char *x) { cout << x << endl; } //Entscheidung mit BarPolicy ist ungefährlich db.decide_something(); }Also erst mal war die Aussage von otze, dass checked Exceptions in C++ nicht funktionieren. Und unter nicht funktionieren versteh ich, dass es ein technische Problem mit dem Compiler gibt bei dem das nicht geht, aber sowas zeigt dein Beispiel nicht. Das man irgendein For-Bar-Beispiel bauen kann bei dem es nicht sinnvoll ist eine checked Exception zu fangen weil sie eigentlich gar nie geworfen wird ist mir auch klar. Das hat aber wenig mit der ganzen Sache zu tun. Wenn eine Methode eine checked Exception wirft, dann muss das auch in der Deklaration angegeben werden. Dann kann der Compiler sagen: Hallo die Methode sagt, sie wirft eine Exception die du fangen musst, aber tust es nicht. Ob in der Methode wirklich Code steht der eine Exception wirft oder nicht ist völlig egal. Das ist das gleiche wie wenn du sagst Parameter für Methoden funktionieren nicht, weil ich irgendwo was mit Templates schreiben kann und da noch nicht weiß welche Parameter ein anderer Programmierer für seine Methode braucht oder ob er nen Errorcode zurückgibt.
Dravere schrieb:
exceptionalcoder schrieb:
Ja ich merk was, dass du nix verstanden hast und dir dabei noch ganz toll vorkommst. Die Einschränkung mit der checked Exception ist nicht größer als die mit dem Namen und den Parametern. Hab ich ja bereits gesagt
Mal ganz ehrlich und ich möchte, dass du die Frage wirklich mal beantwortest. Hast du jemals schon in einem grösseren Projekt C++ Templates eingesetzt?
Ja
Denn mit dem hier:
exceptionalcoder schrieb:
... 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.schränkst du die templates wieder deutlich ein. Es ist nicht klar, ob eine Exception geworfen wird oder ob nicht, das ist es nie! Und es sollte auch nicht vorausgesetzt werden, auch nicht per zusätzlichen template parametern. Das macht die Sache höchstens unheimlich kompliziert oder schränkt die Templatefähigkeiten ungeheuer ein.
Lies das mit der Methoden Deklaration, was ich zu Kreppels Beispiel geschrieben hab
Zudem, wie so oft in C++ gilt halt das folgende:
Der Programmierer trägt die volle Verantwortung!Und darum gibt es in C++ überhaupt keine Typsicherheit und sowas...

Wenn du diese Verantwortung nicht willst, dann programmier halt in Java oder sonst einer Sprache, welche dir gefällt.
Lass doch einfach mal diese dämlichen und schwachsinnigen Sprüche und erzähl mir nicht was ich deiner Meinung nach kann und machen soll, sondern bleib beim technischen.
-
exceptionalcoder schrieb:
Also erst mal war die Aussage von otze, dass checked Exceptions in C++ nicht funktionieren. Und unter nicht funktionieren versteh ich, dass es ein technische Problem mit dem Compiler gibt bei dem das nicht geht, aber sowas zeigt dein Beispiel nicht.
Es ging darum, dass sie nicht in Verbindung mit dem beliebten Policy-Based Design funktionieren.
Man bietet eine Host-Klasse in einer Bibliothek an und will später nichts mehr daran machen müssen und erst Recht sollen die Kunden der Bibliothek die Implementierung der Host-Klasse nicht anpacken müssen. Die Kunden können aber selbst Policies schreiben, die der Host-Klasse per Template-Parameter übergeben werden, denn genau das ist der Sinn von Policy-Based Design. Wenn der Kunde in seiner Policy nun aber plötzlich eine unbekannte Exception wirft, kann sie ja von der ihm zur Verfügung gestellten Host-Klasse überhaupt nicht beachtet werden, weil er sie sich gerade ausgedacht hat. Dann gibt es Compilerfehler, und er soll die womöglich teuer gekaufte Host-Klasse verändern müssen, damit seine neue Exception dort auch noch abgefangen werden kann?
-
Kreppel schrieb:
exceptionalcoder schrieb:
Also erst mal war die Aussage von otze, dass checked Exceptions in C++ nicht funktionieren. Und unter nicht funktionieren versteh ich, dass es ein technische Problem mit dem Compiler gibt bei dem das nicht geht, aber sowas zeigt dein Beispiel nicht.
Es ging darum, dass sie nicht in Verbindung mit dem beliebten Policy-Based Design funktionieren.
Man bietet eine Host-Klasse in einer Bibliothek an und will später nichts mehr daran machen müssen und erst Recht sollen die Kunden der Bibliothek die Implementierung der Host-Klasse nicht anpacken müssen. Die Kunden können aber selbst Policies schreiben, die der Host-Klasse per Template-Parameter übergeben werden, denn genau das ist der Sinn von Policy-Based Design. Wenn der Kunde in seiner Policy nun aber plötzlich eine unbekannte Exception wirft, kann sie ja von der ihm zur Verfügung gestellten Host-Klasse überhaupt nicht beachtet werden, weil er sie sich gerade ausgedacht hat. Dann gibt es Compilerfehler, und er soll die womöglich teuer gekaufte Host-Klasse verändern müssen, damit seine neue Exception dort auch noch abgefangen werden kann?Du hast das mit der Methodendeklaration schon gelesen? Checked Exceptions kommen nicht plotzlich aus dem Code, sondern müssen in der Methodendeklaration angegeben werden. Da kann ich genauso schreiben: Wenn der Kunde in seiner Policy nun aber plötzlich einen weiteren Parameter braucht, kann der ja von der ihm zur Verfügung gestellten Host-Klasse überhaupt nicht beachtet werden, weil er ihn sich gerade ausgedacht hat. Dann gibt es Compilerfehler, und er soll die womöglich teuer gekaufte Host-Klasse verändern müssen, damit seinen neuer Parameter dort auch noch übergeben werden kann?
-
Parameter können auch außerhalb der Host-Klasse an die Policy gebunden werden.
Wie das mit der Methodendeklaration einem Host-Autor helfen soll, wenn er nicht weiß, ob die Methodendeklaration in einer Policy des Kunden später mal throws std::string enthält oder was anderes oder überhaupt keinen Zusatz gemäß throws irgendwas, weiß ich nicht. Was soll man denn in die Host-Klasse reinschreiben, um die unbekannten throws Deklarationen der Kunden zu beachten?
-
Wenn es unbedingt sein muss, dass die Policy Methode checked Exceptions werfen können soll, dann muss die Host Methode halt ein "throws <template exception>" haben und wirft somit eine beliebige Exception der Policy weiter. Die Policy Methode kann auch einfach ne normale Exception werfen und die Hostklasse bekommt garnix davon mit. Nur weil es zusätzliche checked Exceptions gibt, bedeutet das ja nicht, dass es die alten nicht mehr gibt.
-
exceptionalcoder schrieb:
Die Policy Methode kann auch einfach ne normale Exception werfen und die Hostklasse bekommt garnix davon mit. Nur weil es zusätzliche checked Exceptions gibt, bedeutet das ja nicht, dass es die alten nicht mehr gibt.
Wenn das optional wäre, hätte ich nichts dagegen.
-
Wie macht man eigentlich in größeren Projekten mit mehreren Programmieren richtige Fehlerbehandlung? Schreibt man da in die Doku welche Exceptions die Funktion wirft oder verwendet man Errorcodes?
-
wie gehts? schrieb:
Wie macht man eigentlich in größeren Projekten mit mehreren Programmieren richtige Fehlerbehandlung? Schreibt man da in die Doku welche Exceptions die Funktion wirft oder verwendet man Errorcodes?
Man wirft Exceptions. Und checked Exceptions sind da nicht noetig, denn es hat sich herausgestellt dass checked Exceptions zu sehr vielen
try { foo(); } catch(Exception e) {}fuehren - und das ist das schlimmste was es gibt.
Zumal es viele andere Probleme mit checked Exceptions gibt wie zB Versionierung oder eben auch ist es oft der Fall dass die entscheidung ob eine exception eine checked exception ist oder nicht vom client code zu entscheiden ist.
weiters sind exception typen in c++ sehr uninteressant: da man sowieso jede funktion mindestens exception neutral schreibt. man wuerde einfach einen enormen aufwand betreiben muessen bei templates die ganze zeit die checked exception typen durchzureichen.
und man hat eben auch in java bereits eingesehen dass checked exceptions eine nette idee sind, aber in der praxis einfach unpraktisch sind. c# ist ja nach reiflicher ueberlegung ebenfalls weg von exception spezifikationen gegangen.
denn im prinzip ist es einem in den meisten faellen sowieso egal welche exception geflogen ist. denn ob ich die datei nicht lesen kann weil sie gelockt ist, nicht da ist oder ich nicht die noetigen rechte habe sie zu oeffnen ist alles das selbe fuer mich. nur sehr sehr selten will ich das feiner unterscheiden. und da sind checked exceptions halt wieder unpraktisch.
die generelle idee ist zwar super, aber in der praxis funktioniert es nicht so wie es soll. man tauscht im endeffekt nur ein paar probleme gegen ein paar andere - anstatt wirklich probleme zu loesen.
-
@Exceptionalcoder, deine Argumente sind doch totaler Käse. Eine Flut an Warnungen führt zwangsläufig dazu, dass man den Überblick verliert, und bei jedem neukompilieren könnten neue dazukommen (und alte verschwinden - also nichts mit einfach die Anzahl merken!) und sobald du anfängst Warnungen zu deaktivieren weil es zu viel wird bestätigst du meine Behauptung.
Es gibt Compiler da muss man Warnungen abschalten, damit man überhaupt arbeiten kann (z.B. der von VC6, auch wenn der heute veraltet ist, Legacy Projekte gibts noch zu Hauf) und in dem Moment haben die Warnungen einen kontraproduktiven Effekt.Also gleich nur da warnen wo es sinnvoll ist und nicht für jede nichtgefangene Checked Exception eine Warnung generieren.
Checked Exceptions könnten allerdings sinnvoll sein, wenn man das throws-Schlüsselwort so umbaut, dass man Exceptions nicht fangen muss sondern explizit weiterwerfen kann, so würde man kurz schauen ob man die Exception behandeln kann und wenn nicht, gibt man an, dass man sie weiterwerfen will.
Ohne leere try-catch-Blöcke mit throw drin, oder ähnliche Monster.Übrigens dein Argument mit 5 Stunden irgendwas - was hat das mit der Dikussion zu tun? Eine nichtgefangene Exception würde so oder so das Programm terminieren, nur der Unterschied ist bei einer echten Anwendung wäre ganz oben zumindest ein catch-All-Block, so dass das Programm nicht auf die Böse Art endet, sondern ne schöne Fehlermeldung anzeigt und Informationen für den Fehler sammelt und abspeichert.
Und natürlich wäre weiter unten auch ein catch-Block welcher versucht die Daten noch in einer Datei zu speichern vorm Terminieren der Anwendung.Ich sehe nicht inwiefern dein Beispiel den Sinn/Unsinn von Checked Exceptions belegt.
-
Ich glaube, checked Exceptions sind ein reichlich unverstandener Mechanismus.
-
Exceptionist schrieb:
@Exceptionalcoder, deine Argumente sind doch totaler Käse. Eine Flut an Warnungen führt zwangsläufig dazu, dass man den Überblick verliert, und bei jedem neukompilieren könnten neue dazukommen (und alte verschwinden - also nichts mit einfach die Anzahl merken!) und sobald du anfängst Warnungen zu deaktivieren weil es zu viel wird bestätigst du meine Behauptung.
Es gibt Compiler da muss man Warnungen abschalten, damit man überhaupt arbeiten kann (z.B. der von VC6, auch wenn der heute veraltet ist, Legacy Projekte gibts noch zu Hauf) und in dem Moment haben die Warnungen einen kontraproduktiven Effekt.Du wolltest mit blöden Warnings anfangen, normal sind es Errors und die lenken nicht von den anderen warnings ab
Checked Exceptions könnten allerdings sinnvoll sein, wenn man das throws-Schlüsselwort so umbaut, dass man Exceptions nicht fangen muss sondern explizit weiterwerfen kann, so würde man kurz schauen ob man die Exception behandeln kann und wenn nicht, gibt man an, dass man sie weiterwerfen will.
Ohne leere try-catch-Blöcke mit throw drin, oder ähnliche Monster.Das mit throws funktioniert so wie du es willst.

Übrigens dein Argument mit 5 Stunden irgendwas - was hat das mit der Dikussion zu tun? Eine nichtgefangene Exception würde so oder so das Programm terminieren, nur der Unterschied ist bei einer echten Anwendung wäre ganz oben zumindest ein catch-All-Block, so dass das Programm nicht auf die Böse Art endet, sondern ne schöne Fehlermeldung anzeigt und Informationen für den Fehler sammelt und abspeichert.
Und natürlich wäre weiter unten auch ein catch-Block welcher versucht die Daten noch in einer Datei zu speichern vorm Terminieren der Anwendung.LOL. Wieder mal ein "Ich bin zu blöd richtige Fehlerbehandlung zu machen also sind alle Exceptions schlecht"-Argument. Das was du schreibst kann man auch mit normalen Exceptions machen.
Mal wieder nur Argumente die keine sind, sondern nur aus deinem Unwissen stammen. Das wird jetzt langsam langweilig.
-
ShadeOfMine schrieb:
wie gehts? schrieb:
Wie macht man eigentlich in größeren Projekten mit mehreren Programmieren richtige Fehlerbehandlung? Schreibt man da in die Doku welche Exceptions die Funktion wirft oder verwendet man Errorcodes?
Man wirft Exceptions....
weiters sind exception typen in c++ sehr uninteressant: da man sowieso jede funktion mindestens exception neutral schreibt. man wuerde einfach einen enormen aufwand betreiben muessen bei templates die ganze zeit die checked exception typen durchzureichen.
Was mit checked exceptions gehen würde oder nicht interessiert mich nicht, da es sie sowieso nicht gibt. Ich möchte wissen wie es jetzt umgesetzt wird.
Die stellen, die mir einfallen, an denen es sinnvoll ist exceptions zur fehlerbehandlung zu verwenden sind lese/schreibzugriffe auf datei/db/server... Wie macht ihr das da? Woher wisst ihr welche exception von welchem typ man jetzt fangen muss, schreibt ihr das in den Kommentar? Oder gebt ihr einfach NULL zurück und prüft dann auf das? Oder was macht ihr?
Die exceptions die nur für sowas wie ungültiger arrayindex da sind, sind doch nur für programmierfehler und ne sinnvolle fehlerbehandlung ist sowieso nicht möglich, oder?
-
LOL. Wieder mal ein "Ich bin zu blöd richtige Fehlerbehandlung zu machen also sind alle Exceptions schlecht"-Argument. Das was du schreibst kann man auch mit normalen Exceptions machen.
LOL. Wieder mal ein "Ich bin stur um andere Argumente zu akzeptieren also picke ich mir die raus, die ich wiederlegen kann"
Mal ehrlich, es wurde genügend Argumente genannt...
-
wie gehts? schrieb:
Die stellen, die mir einfallen, an denen es sinnvoll ist exceptions zur fehlerbehandlung zu verwenden sind lese/schreibzugriffe auf datei/db/server... Wie macht ihr das da? Woher wisst ihr welche exception von welchem typ man jetzt fangen muss, schreibt ihr das in den Kommentar? Oder gebt ihr einfach NULL zurück und prüft dann auf das? Oder was macht ihr?
Die exceptions die nur für sowas wie ungültiger arrayindex da sind, sind doch nur für programmierfehler und ne sinnvolle fehlerbehandlung ist sowieso nicht möglich, oder?
Jede Art von Laufzeitfehler ist eine Exception.
Es gibt 2 Arten von Fehlern: Logische und Laufzeitfehler.Logische Fehler sind zB einen null zeiger an ein fstream Objekt zu geben um es zu oeffnen. Oder ein div by zero fehler.
Alles was in einem fehlerfreien programm nicht auftreten kann ist ein logischer fehler - oder statischer wenn man so will.
Laufzeitfehler sind dann alles andere: zB datei wurde nicht gefunden, verbindung zur datenbank wurde abgebrochen. nicht genug speicher vorhanden, etc.
errorcodes sind nur dann sinnvoll wenn man keine exception verwenden kann (zB weil es ueber binary grenzen hinaus geht).
-
Shade Of Mine schrieb:
wie gehts? schrieb:
Die stellen, die mir einfallen, an denen es sinnvoll ist exceptions zur fehlerbehandlung zu verwenden sind lese/schreibzugriffe auf datei/db/server... Wie macht ihr das da? Woher wisst ihr welche exception von welchem typ man jetzt fangen muss, schreibt ihr das in den Kommentar? Oder gebt ihr einfach NULL zurück und prüft dann auf das? Oder was macht ihr?
Die exceptions die nur für sowas wie ungültiger arrayindex da sind, sind doch nur für programmierfehler und ne sinnvolle fehlerbehandlung ist sowieso nicht möglich, oder?
Jede Art von Laufzeitfehler ist eine Exception.
Es gibt 2 Arten von Fehlern: Logische und Laufzeitfehler.Logische Fehler sind zB einen null zeiger an ein fstream Objekt zu geben um es zu oeffnen. Oder ein div by zero fehler.
Alles was in einem fehlerfreien programm nicht auftreten kann ist ein logischer fehler - oder statischer wenn man so will.
Laufzeitfehler sind dann alles andere: zB datei wurde nicht gefunden, verbindung zur datenbank wurde abgebrochen. nicht genug speicher vorhanden, etc.
errorcodes sind nur dann sinnvoll wenn man keine exception verwenden kann (zB weil es ueber binary grenzen hinaus geht).
Das ist die Theorie. Mich interessiert die Praxis. Wie macht ihr das zum Beispiel beim speichern? Wenn z.B. eine Datei auf Festplatte gespeichert werden soll und der User wählt ein schreibgeschützes Laufwerk. Was macht ihr dann? Man wählt in der GUI über nen File Dialog ne Datei aus. Dann wird ne save Methode aufgerufen und die kann fehlschlagen. Last ihr jetzt die save Methode ne exception werfen und wenn ja, woher weiß der GUI Programmierer welche? Oder was macht ihr?
-
wie gehts? schrieb:
Oder was macht ihr?
ja, eine exception fliegt.
was ist daran komisch oder verwirrend?natuerlich wird die exception auch wieder gefangen.
was genau willst du wissen oder wie genau stellst du dir programmieren vor? dass man fehler einfach ignoriert oder wie?
-
Toni, es ging dem Fragesteller glaube ich nicht um die Ausnahme, sondern darum, wie man sie kommuniziert.
Und die Antwort lautet: In Projekten, in denen ich bisher mitgearbeitet habe, wurde das durch die Dokumentation erreicht.