C++0x checked exceptions?
-
Optimizer schrieb:
Wenn du Exception-Handling für deine Policies brauchst (wovon ich in den meisten Fällen nicht ausgehe), definierst du eine eigene Exception "kann dies und das nicht machen" und einigst dich darauf, dass alle Policies nur diese Exception werfen dürfen.
Das ist u.U. eine zu starke Einschränkung.
Das ist Standard-Vorgehen das du auch ohne checked Exceptions benötigst, wie könntest du sonst deinen Code absichern?
Nein. Der Client weiß ja üblicherweise (zumindest irgendwo), welche Policy er verwendet, d.h. er weiß auch (irgendwo), welche Ausnahmen auftreten können und kann dort (= irgendwo) entsprechend reagieren. Das geht aber eben nur, wenn die Policy-parametrisierte Klasse diese Ausnahme überhaupt zulässt, und das ist eben durch Checked Exceptions stark beschnitten.
Wenn du Policy-Objekte benutzt, hast du gewisse Annahmen darüber, wie sie sich verhalten
Das ist eben nicht unbedingt der Fall. Zumindest nicht aus Sicht der allgemeinen, parametrisierten Klasse. Der Client macht natürlich Annahmen, aber der hat leider keinen Einfluss auf die von der parametrisierten Klasse erlaubten Ausnahmen.
=> Ich habe den Eindruck, dass Du hier die verschiedenen Akteure im Programmfluss durcheinanderbringst.
-
ihr stellt euch an. wenns Checked-Exceptions gäbe, warum sollte man dann den Exceptiontyp nicht per Template festlegen können? Fertig, Policy-Prinzip geht wieder.
-
Optimizer schrieb:
Bashar schrieb:
Wenn ich eine neue Exception werfe, dann breche ich Clientcode. Und zwar immer.
Nö, der Clientcode kann ja die Exception in Klasse A einführen und in B fangen, aber dazwischen sitzt ein generisches Framework, das dank Checked Exceptions die Exception nichtmal einfach durchreichen kann. Danke aber auch.
Also hab ich nicht den direkt abhängigen Clientcode gebrochen, sondern den indirekt abhängigen.
Kannst du das ausführen? Was meinst du mit indirekt abhängigem Clientcode, und warum sollte dieser gebrochen sein?
-
Optimizer schrieb:
Wenn du Exception-Handling für deine Policies brauchst (wovon ich in den meisten Fällen nicht ausgehe),
Eine der häufigsten Policies die ich kenne hat mit dem Anlegen und Freigeben zu tun. Je nach Policy, die auch ein Anwender der Klasse selbst definieren kann, muss es dabei nicht zwangsläufig sein das die generierung überhaupt Fehlschlagen kann (Nehmen wir einfach mal an das hier garkein neues Objekt generiert, sondern im Hintergrund einfach nur auf ein statisches Array zugegriffen wird).
Zudem kann der Schreiber der Policy dann auch auf Ideen kommen die du garnicht in deinen Entwurf berücksichtigt hast. Und nun? Tolle Einschränkung, echt Klasse.
Optimizer schrieb:
definierst du eine eigene Exception "kann dies und das nicht machen" und einigst dich darauf, dass alle Policies nur diese Exception werfen dürfen.
Du solltest dich vielleicht mal überhaupt mit dem Thema Policy-Klassen genauer beschäftigen. Es gibt bei Policy-Klassen auch keinerlei...
Optimizer schrieb:
Wenn du Policy-Objekte benutzt, hast du gewisse Annahmen darüber, wie sie sich verhalten und Exceptions gehören zu diesem Verhalten dazu.
Annahmen zu den Klassenaufbau. Das Einzige was du vielleicht fest machst ist das eine Methode mit dem und dem Namen vorhanden sein muss. Wobei Policies auch weit über deine Annahmen hinaus gehen können.
Optimizer schrieb:
Wenn du keine Annahmen darüber machen kannst, kannst du deinen Code auch nicht absichern. Das Checking verursacht die Probleme also nicht, sondern zeigt die bereits vorhandenen nur auf.
Du als Anwender der Policies kannst sehr wohl Annahmen über die Policies treffen, nicht aber der Entwickler des Klassentemplates das aus den Policies aufgebaut wird. Daher kann eben dieser KEINERLEI "checked exceptions" verwenden, ohne den Anwender die Flexibilität zu nehmen.
Optimizer schrieb:
Ich sehe aber keinen Konflikt mit üblichen Paradigmen.
Ich schon Policy-Klassen und "checked exceptions" widersprechen sich. Wenn du anderer Meinung bist, solltest du dich auch erstmal ernsthaft mit dem Thema Policy-Klassen auseinander setzen. Nach deinen Geschreibe gehe ich davon aus das du maximal die Grundlagen darüber mal gehört, aber es noch nie ernsthaft angewendet, oder nur mit den vordefinierten Policies hantiert hast.
Und Policy-Klassen sind nur eine der Templatetechniken die als Beispiel genannt wurden sind. Grundsätzlich sehe ich auch bei einfach verschachtelten Templates (Die über typedefs aus anderen Templates aufgelöst werden), Große Probleme bezüglich "checked exceptions".
cu André
-
mannn schrieb:
ihr stellt euch an. wenns Checked-Exceptions gäbe, warum sollte man dann den Exceptiontyp nicht per Template festlegen können? Fertig, Policy-Prinzip geht wieder.
Dann müsste man das aber noch ganz stark ausweiten. Ich sage mal bedingte checked-exceptions (Da eine Policy zwischen 0..n Exceptionfälle haben kann) etc.
Weiß du, man kann auch mit einem Ferrari einen Brief zum 10m entfernten Briefkasten bringen, oder mit einem Bobbycar von München nach Hamburg fahren. In wie weit das Sinn macht, ist die andere Frage.
Manche bezeichnen C++ schon jetzt als komplexe Sprache, wieviele Sprachmittel braucht es eigentlich noch?
cu André
P.S: Tatsächlich würde ich mir von C++ Standard noch 2 Sachen wünschen:
a) Eine portable Definition um über Schnittstellen auch mit C++ Elementen Daten auszutauschen (Auch über Compilergrenzen hinweg).
b) Eine UI-Bibliothek die auch tatsächlich die Standardlib einsetzt (Sprich auch mit std::string, std::wstring etc. klar kommt).
-
Optimizer schrieb:
Bashar schrieb:
Wenn ich eine neue Exception werfe, dann breche ich Clientcode. Und zwar immer.
Nö, der Clientcode kann ja die Exception in Klasse A einführen und in B fangen, aber dazwischen sitzt ein generisches Framework, das dank Checked Exceptions die Exception nichtmal einfach durchreichen kann. Danke aber auch.
Also hab ich nicht den direkt abhängigen Clientcode gebrochen, sondern den indirekt abhängigen. Wir verstecken den Fehler immer besser, nähern uns bald der Perfektion.

nein, weil der typ egal ist. client code der bricht weil ein anderer typ exception geflogen ist, ist kaputt. es kann zB immer ein out of memory fliegen und das fange ich nie explizit ab - aber dafür habe ich ja generisches exception handling dass eben exception bearbeitet ohne sie kennen zu müssen.
Wenn dich der Exception-Typ nicht interessiert, dann fang doch in deinem Clientcode die allgemeine Exception. Dann stört es dich auch nicht, wenn der andere seine Spezifikation etwas anpasst. Wenn du z.B. eine allgemeine IOException fängst weil es dir reicht zu wissen dass eine Datei nicht geladen wurde, dann ist es dir auch egal, wenn ich nachträglich noch eine AccesDeniedException hinzufüge.
Das Problem ist nur, dass es nicht nur IOException gibt sondern auch SecurityException und eine OutOfMemoryException kann sowieso ach noch immer fliegen. Eine Datei Operation kann eben auch anderes als IOExceptionmäßiges werfen.
Beispiel eine Datenbank. Am Anfang kann nur eine DatabaseAccessException fliegen. Später plötzlich kommen Security Policies dazu und ich habe das Problem dass ich SecurityPolicy Exception plötzlich zwangsläufig in die DatabaseAccessException hierachie packen muss anstatt die bestehende Hierachie zu verwenden.
Der Typ von Objekten ist in der oop immer egal. vorallem vielen funktionen sind exception total egal: man nennt sie exception neutrale funktionen. sie werfen alle exception einfach durch.
mit templates ist es sowieso unmöglich checked exceptions sinnvoll zu forcieren. es ist eben nicht sinnvoll machbar exception restriktionen an policies zu setzen da man dadurch die wiederverwendbarkeit senkt. auch in java tut man sich mittlerweile schwer und ist zu dem konsens gekommen dass checked exception eine nette idee waren und mehr nicht.
siehe auch: http://www.mindview.net/Etc/Discussions/CheckedExceptions
aber wir haben diese diskussion schon vor vielen jahren geführt

-
Bashar schrieb:
Kannst du das ausführen? Was meinst du mit indirekt abhängigem Clientcode, und warum sollte dieser gebrochen sein?
Vielleicht verstehe ich dich falsch. Wenn du in deinem Beispiel meintest man hätte die Möglichkeit, B an die neue Spezifikation anzupassen, nur das Framework dazwischen nicht, dann ist das möglicherweise schon ein guter Punkt.
Ich möchte aber auch anmerken, dass so ein Framework normalerweise aus einem guten Grund existiert und das Framework unter Umständen dafür verantwortlich sein müsste, die Exception zu fangen und darauf zu reagieren. Vielleicht hast du in deinem B die Möglichkeit, die Exception zu fangen, aber das ist nicht notwendigerweise sinnvoll. Nimm zum Beispiel:
Anwendung <-> O/R-Mapper <-> Datenbank
Und das Datenbanksystem könnte jetzt eine neue Exception werfen. Der O/R-Mapper hat die Aufgabe, die Tabellen umzufüllen in andere Strukturen und dabei transparent Details der Datenbank, wie z.B. das aufrechterhalten der Verbindung zu verbergen und macht in diesem Sinne auch das Exception-Handling "Socket kann nicht erstellen werden" oder "insert MS SQL Server specific error here" und zeigt der Anwendung etwas allgemeineres an.
Jetzt würdest du bestimmt gar nicht wollen, dass du in deiner Anwendung irgendwelche MS SQL-Fehler fangen musst, die neu hinzukommen. Es ist also ohnehin nötig, das Framework anzupassen und "einfach durchreichen" ist keine Lösung.
-
Optimizer schrieb:
Jetzt würdest du bestimmt gar nicht wollen, dass du in deiner Anwendung irgendwelche MS SQL-Fehler fangen musst, die neu hinzukommen. Es ist also ohnehin nötig, das Framework anzupassen und "einfach durchreichen" ist keine Lösung.
ich würde das nicht machen, wenn das framework nicht fangen soll.
dem framework sind die fehler doch egal. wenn die db keine daten liefert die das framework verarbeiten kann, reicht es den fehler durch. punkt.natürlich kann man es auch anders machen, aber es gibt keinen zwingenden grund...
-
Ja, ist jetzt schon auch egal. Ich möchte nicht für checked Exceptions argumentieren und habe seit Jahren mit keiner Sprache mehr gearbeitet, die sowas anbietet. Ich vermisse es auch nicht. Ich habe einfach den Eindruck, dass viel Abneigung aus Misverständnissen entsteht und gerade so einfache Logik wie "ich kann nichts mehr nachträglich ändern" ist mir zu kurz gedacht. Das checked Exceptions in C++ dann nicht genauso aussehen würden wie in Java, scheint auch nicht immer klar zu sein.
Auf jeden Fall würden checked Exceptions für mich ohnehin ein non-Problem lösen, ich bin schon froh, wenn im Team überhaupt Exceptions benutzt werden oder irgendeine Art von Fehlersignalisierung anstatt eines silent return.
Deswegen ist diese ganze Diskussion für mich eher akademisch interessant.
-
Shade Of Mine schrieb:
Optimizer schrieb:
Jetzt würdest du bestimmt gar nicht wollen, dass du in deiner Anwendung irgendwelche MS SQL-Fehler fangen musst, die neu hinzukommen. Es ist also ohnehin nötig, das Framework anzupassen und "einfach durchreichen" ist keine Lösung.
ich würde das nicht machen, wenn das framework nicht fangen soll.
dem framework sind die fehler doch egal. wenn die db keine daten liefert die das framework verarbeiten kann, reicht es den fehler durch. punkt.natürlich kann man es auch anders machen, aber es gibt keinen zwingenden grund...
Aber du hast schon verstanden, dass das Framework vom konkreten DBS abstrahieren soll, oder? Es macht dann wohl kaum Sinn, eine "Windows Anmeldung nicht erfolgreich wegen Domain-Problem xyz"-Exception durchzureichen. Das ist ohnehin für die Anwendung nicht verwertbar, die gerade einen Datensatz anfordern wollte.
-
asc schrieb:
...
P.S: Tatsächlich würde ich mir von C++ Standard noch 2 Sachen wünschen:
a) Eine portable Definition um über Schnittstellen auch mit C++ Elementen Daten auszutauschen (Auch über Compilergrenzen hinweg).
b) Eine UI-Bibliothek die auch tatsächlich die Standardlib einsetzt (Sprich auch mit std::string, std::wstring etc. klar kommt).c) Ein vernünftiger Umgang mit Datum/Zeit.
Gruß,
Simon2.
-
Simon2 schrieb:
asc schrieb:
...
P.S: Tatsächlich würde ich mir von C++ Standard noch 2 Sachen wünschen:
a) Eine portable Definition um über Schnittstellen auch mit C++ Elementen Daten auszutauschen (Auch über Compilergrenzen hinweg).
b) Eine UI-Bibliothek die auch tatsächlich die Standardlib einsetzt (Sprich auch mit std::string, std::wstring etc. klar kommt).c) Ein vernünftiger Umgang mit Datum/Zeit.
d) ein vernünftiger und portabler weg für unicode streams.
-
Optimizer schrieb:
Aber du hast schon verstanden, dass das Framework vom konkreten DBS abstrahieren soll, oder? Es macht dann wohl kaum Sinn, eine "Windows Anmeldung nicht erfolgreich wegen Domain-Problem xyz"-Exception durchzureichen. Das ist ohnehin für die Anwendung nicht verwertbar, die gerade einen Datensatz anfordern wollte.
Das ist deine Definition. Es wäre aber durchaus auch denkbar dass das framework diese arbeit eben nicht macht und fehler durchreicht.
gerade im oo design kommt es so oft vor dass du auf daten und objekten operierst die du nicht kennst, die dir auch egal sind. wenn ich sage waldi.gib_laut() und der waldi kann nicht laut geben ist es mir total egal warum er es nicht kann. deshalb bin ich hier exception neutral und reiche die exception schön sauber durch.
checked exception verlangen dass ich mich lokal damit auseinandersetze - ob ich es will oder nicht. und genau das ist der punkt. deshalb auch die studie von microsoft zu checked exceptions in c#:
Examination of small programs leads to the conclusion that requiring exception specifications could both enhance developer productivity and enhance code quality, but experience with large software projects suggests a different result -- decreased productivity and little or no increase in code quality.
checked exception tauschen einen satz von problemen gegen einen anderen satz an problemen. sie lösen deshalb probleme nicht wirklich, man verschiebt sie nur. ich denke niemand hat etwas gegen die idee - aber versioning ist eben mit checked exceptions ein problem. das ist nicht kurzsichtig gedacht sondern es liegt daran dass mir der typ der exception einfach total egal ist. in 99% der fälle will ich wissen: fehler oder nicht fehler. und genau das machen checked exception schwerer (aber eben auch by design).
die ganze idee hinter checked exception ist es exception handling anstrengend zu machen. der vorteil liegt auf der hand: man wird zum behandeln von fehlern gezwungen. der nachteil ist aber: man wird zum behandeln von fehlern gezwungen

-
Shade Of Mine schrieb:
die ganze idee hinter checked exception ist es exception handling anstrengend zu machen. der vorteil liegt auf der hand: man wird zum behandeln von fehlern gezwungen. der nachteil ist aber: man wird zum behandeln von fehlern gezwungen
ne, man soll exceptions zur kenntnis nehmen. das ist ein wichtiger unterschied. wenn man eine exception nicht behandeln will, oder kann, listet man sie z.b. im throws-statement im funtionskopf auf und ist sie damit los. blöd finde ich programmiersprachen, mit der man exceptions stillschweigend ignorieren kann. solche exceptions sind kein bisschen besser, als simple rückgabewerte.

-
fricky schrieb:
blöd finde ich programmiersprachen, mit der man exceptions stillschweigend ignorieren kann. solche exceptions sind kein bisschen besser, als simple rückgabewerte.
Behauptung ohne Beleg. Außerdem: Du findest es also doof, dass Java neben den Checked Exceptions auch Unchecked Exceptions kennt?
-
fricky schrieb:
blöd finde ich programmiersprachen, mit der man exceptions stillschweigend ignorieren kann. solche exceptions sind kein bisschen besser, als simple rückgabewerte.
Welche Sprache findest du dann nicht blöd? Checked Exception gibt es (was bedeutende Programmiersprachen angeht) nur in Java. Selbst in C# wurden sie niucht eingeführt. Es war halt ein Experiment, aber die Erfahrung zeigt, dass checked Exeptions eher Probleme schaffen als lösen.
Außerdem werden die Exceptions ja nicht komplett ignoriert wie etwa Rückgabewerte. Sie werden nach oben geworfen und führen ltztlich zum Programmabbruch bzw. einem Fehlerreport. Was will man mehr?
-
Wann kann man den schon sinnvoll was mit Exceptions anfangen was man dann dem User mitteilen kann? Das Problem an den Java checked Exceptions ist doch, dass es zuviele gibt mit denen man eigentlich nix sinnvolles machen kann. Bei IOExceptions kann man das dem User anzeigen, dass er dann z.B. ne andere Datei wählen kann. Aber wieso sind NoSuchFieldException, ClassNotFoundException, AlreadyBoundException, CloneNotSupportedException, UnsupportedCallbackException, AWTException usw. checked? Was soll der User da groß machen? Das ist doch fast immer ein Grund das Programm zu beenden, weil irgendwas exterm schief gelaufen ist.
-
Simon2 schrieb:
asc schrieb:
...
P.S: Tatsächlich würde ich mir von C++ Standard noch 2 Sachen wünschen:
a) Eine portable Definition um über Schnittstellen auch mit C++ Elementen Daten auszutauschen (Auch über Compilergrenzen hinweg).
b) Eine UI-Bibliothek die auch tatsächlich die Standardlib einsetzt (Sprich auch mit std::string, std::wstring etc. klar kommt).c) Ein vernünftiger Umgang mit Datum/Zeit.
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2615.html, letzte Woche glaub' ich verabschiedet.
otze schrieb:
d) ein vernünftiger und portabler weg für unicode streams.
http://en.wikipedia.org/wiki/C%2B%2B09#New_string_literals
Ich hätte die Module gerne gesehen.
-
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2615.html, letzte Woche glaub' ich verabschiedet.
Nicht das was Simon2 meinte. Das da oben ist ja wohl sehr low level, mehr für Threading u.ä.
Für TR2 ist aber Boost.date vorgeschlagen. DAS ist Zeit/Datums-Behandlung.
-
.filmor schrieb:
otze schrieb:
d) ein vernünftiger und portabler weg für unicode streams.
String != Stream. Ohne vernünftiges Handling nutzen die Literale außerdem gar nichts. Und soweit ich weiß, ist da nichts geplant (also z.B. Unicode-Normalisierungen, Konvertierungen etc.).