Fehlerbehandlung in einer Engine



  • Tippgeber schrieb:

    Shade Of Mine schrieb:

    [...]

    Init Methoden sind fast immer eine schlechte wahl.

    Nicht unbedingt, im Falle von DirectX sogar sehr sinnvoll. Allerdings würde ich die Methode nicht Init nennen, sondern OnDeviceLost bzw. Reset, nämlich in diesem Fall muss man die Daten neu laden (und man hat nicht immer die Modell-Datei noch im Speicher geschweige denn die Texturen).

    Xebov, schau dir doch einmal das DXUT Sample Framework an und nutze das zur groben Orientierung, gerade solche Fehlerfälle und Windows-Fallstricke werden dort vorbildlich behandelt (auch wenn ich den Coding-Style nicht mag) 🙂

    Zur Klarstellung: ich meine nicht die Fehlerbehandlung an sich, sondern, dass sie Fehler behandeln bzw. welche möglichen Fehler sie behandeln.

    Besonders interressant ist auch die Render-Loop, echt erstaunlich was da alles schief gehen kann.



  • Shade Of Mine schrieb:

    Warum ist das kompliziert?

    LoadModel lädt das Modell + alle Texturen. Wenn eine textur nicht lädt, dann default textur laden, lädt die auch nicht dann die exception weiter reichen an den anrufer und irgendwer wird sich verantwortlich fühlen und eine fehlermeldung ausgeben.

    Ja genau das, nur die muß ja erstmal dahin deswegen ja auch die Idee mit der static Variable die eine Standart textur hält.

    Shade Of Mine schrieb:

    Welche Probleme denn?

    Init Methoden sind fast immer eine schlechte wahl.

    Nehmen wir mal folgende Sache An, ich habe mehrere Modelle, sagen wir 5, die will ich alle Laden, der einfachheit halber mache ich zB ein Array, wenn ich Init verwende kann ich new Model[5] machen und sie danach einzelln mit Init Initialisieren, wenn ich kein init habe dann muß ich sie einzelln erstellen und Initialisieren weil sie der Konstruktor will.

    Ich fidne auch Init Methoden generell nicht schlecht, meine Klassen überschreiben beim erstellen im Konstruktor nur einige Variablen mit 0en und setzen einige andere, das kann eigentlich fats nicht shcief gehen, damit würde die Konstruktion eines Objekts immer gelingen, wenn Init Fehlschlägt, das die meiste Arbeit macht könnte man ne Exception werfen und einfach den Zustand des konstruktors wieder herstellen damit würde ein fehlschlag beim Laden der Datei zB trotzdem ein Unitialisiertes Model hinetrlassen das keine Korrupten Daten hat, wenn ich im Konstruktor ne exception habe könnte ich das Objekt ja im Grunde direkt wegwerfen und neu erstellen weil der Zustand irgendwo gelandet ist.

    Das beispiel mit den fehlern werd ich mir direkt mal anschaun danke für den Tip.



  • Nachtrag:
    Gerade bin ich wieder über ein Stück Code gestolpert, das hervorragend demonstriert, warum Exceptions besser sind.
    http://blogs.msdn.com/oldnewthing/archive/2004/07/20/188696.aspx



  • Tja, ich habe schon Code gesehen, der optisch genauso aussieht, nur anstatt if mit try/catch arbeitet (z.B. "generieter" Code von Fujaba). Es gibt auch Beispiele wo Exceptions schneller sind, z.B. komplexe Baumtraversierung auf der Such nach einem bestimmten Knoten. Anstatt staendig Rueckgabewerte abzufragen, wird einfach eine Exception bei Erfolg geworfen und das Suchergebnis dort drin verpackt. Das gelinkte Beispiel habe ich nur ueberflogen und vielleicht ist auch eine bessere Loesung ohne Exceptions moeglich. Ausserdem ist es etwas unserioes, schlechte Programmbeispiele herzunehmen und die Vorteile von Exceptions dadurch zu begruenden. Prinzipiell habe ich nichts gegen Exceptions, aber ich bin eher vorsichtig. Sie schuetzen auch nicht vor schlechten Programmierstil.



  • knivil schrieb:

    Tja, ich habe schon Code gesehen, der optisch genauso aussieht, nur anstatt if mit try/catch arbeitet

    Dann hat jemand try/catch und RAII nicht verstanden.

    knivil schrieb:

    Das gelinkte Beispiel habe ich nur ueberflogen und vielleicht ist auch eine bessere Loesung ohne Exceptions moeglich. Ausserdem ist es etwas unserioes, schlechte Programmbeispiele herzunehmen und die Vorteile von Exceptions dadurch zu begruenden.

    Es ist ein Extrembeispiel, dennoch kann es prozedural niemals auf eine Weise vereinfacht werden, die Exceptions und RAII anbieten.

    knivil schrieb:

    Prinzipiell habe ich nichts gegen Exceptions, aber ich bin eher vorsichtig. Sie schuetzen auch nicht vor schlechten Programmierstil.

    Nein, aber sie ermöglichen einen sauberen Programmierstil, der wenn man erst einmal passende RAII-Objekte hat sich auch deutlich besser lesen und warten lässt (In dem von audacia gezeigten Negativbeispiel würde mittels RAII vermutlich nur eine Verschachtelungsebene => Ein try-catch Block stehen [wenn überhaupt an dieser Stelle sinnvoll]).

    cu André



  • Dann hat jemand try/catch und RAII nicht verstanden.

    Ich weise einfach nochmal darauf hin, dass ich RAII auch mit if machen kann und ich es deswegen nicht als Argument zaehle. Sind gute Gruende fuer Exceptions, ohne gleich RAII ins Bot zu holen, schwer zu finden?

    Es ist ein Extrembeispiel, dennoch kann es prozedural niemals auf eine Weise vereinfacht werden, die Exceptions.

    Wage Behauptung, leider habe ich keine Lust dir das Gegenteil zu programmieren.

    aber sie ermöglichen einen sauberen Programmierstil

    Und if verhindert keinen sauberen Programmierstil (RAII siehe Anfang). So, what's the point?

    (Zumal das Beispiel kaum was mit sauberer Programmierung und C++ zu tun hat. Suchen wir uns einen schwachen Gegener (wie dieses Programm) und bauen unsere Argumentation darauf auf. Ein elegantes Beispiel, was durch Exceptions noch eleganter wird, ist wesentlich ueberzeugender.)



  • knivil schrieb:

    Dann hat jemand try/catch und RAII nicht verstanden.

    Ich weise einfach nochmal darauf hin, dass ich RAII auch mit if machen kann und ich es deswegen nicht als Argument zaehle. Sind gute Gruende fuer Exceptions, ohne gleich RAII ins Boot zu holen, schwer zu finden?

    Hast du schon einmal daran gedacht, dass Exceptions ohne RAII keinen Sinn machen könnten?

    Im ürbigen kann es uns doch herzlich egal sein ob du krampfhaft dein Code mit ifs zukleistern willst.



  • @mein-fan:
    Exceptions machen durchaus Sinn ohne RAII. Trotzdem wuerde ich fuer das Negativbeispiel keine Exceptions einsetzen, RAII vielleicht. "krampfhaft dein Code mit ifs zukleistern" tue ich nicht, es gibt so viele Moeglichkeiten if's zu vermeiden.



  • knivil schrieb:

    Exceptions machen durchaus Sinn ohne RAII.

    M.M.n. nur in Verbindung mit "finally" (was es unter C++ ja so nicht gibt).



  • knivil schrieb:

    Tja, ich habe schon Code gesehen, der optisch genauso aussieht, nur anstatt if mit try/catch arbeitet (z.B. "generieter" Code von Fujaba). Es gibt auch Beispiele wo Exceptions schneller sind, z.B. komplexe Baumtraversierung auf der Such nach einem bestimmten Knoten. Anstatt staendig Rueckgabewerte abzufragen, wird einfach eine Exception bei Erfolg geworfen und das Suchergebnis dort drin verpackt.

    Der Schuß kann aber doch auch sehr schnell mal nach hinten losgehen oder?



  • knivil schrieb:

    asc schrieb:

    Dann hat jemand try/catch und RAII nicht verstanden.

    Ich weise einfach nochmal darauf hin, dass ich RAII auch mit if machen kann und ich es deswegen nicht als Argument zaehle. Sind gute Gruende fuer Exceptions, ohne gleich RAII ins Bot zu holen, schwer zu finden?

    1. Rede ich hier von dem, was normalerweise unter RAII verstanden wird. Und nein, das lässt sich nicht sinnvoll mit if-Verzweigungen nachbauen (Zumindest wenn in dem Code außer Rückgabewerten noch exceptions möglich sind).

    2. Ich esse mein Essen in der Regel mit Besteck, auch wenn man die Hände verwenden, und Besteck auch für anderes als Essen nutzen kann. Am meisten Sinn ergeben sie vor allem in Kombination. Ähnlich ist es mit RAII und dem Thema Exceptions - Gerade in C++ ist der Sinn des Einen, vor allem (Aber nicht Ausschließlich) in der Kombination mit dem Anderen sinnvoll.

    knivil schrieb:

    asc schrieb:

    Es ist ein Extrembeispiel, dennoch kann es prozedural niemals auf eine Weise vereinfacht werden, die Exceptions.

    Wage Behauptung, leider habe ich keine Lust dir das Gegenteil zu programmieren.

    Schade, da ich mal sehen will wie du das hinbekommen willst. Mit RAII & Exceptions wäre das Beispiel (vorausgesetzt man schreibt zudem auch die RAII-Objekte) ein 20 Zeiler, mit if-Schachtelungen wirst du das nicht hinbekommen. Und selbst wenn wir den Code der RAII-Objekte mitrechnen, wirst du über ein Gesamtprojekt eher ganz massiv Code einsparen (Da man diese Objekte dann auch in mehr als einen Aufruf verwendet).

    knivil schrieb:

    asc schrieb:

    aber sie ermöglichen einen sauberen Programmierstil

    Und if verhindert keinen sauberen Programmierstil (RAII siehe Anfang). So, what's the point?

    (Zumal das Beispiel kaum was mit sauberer Programmierung und C++ zu tun hat. Suchen wir uns einen schwachen Gegener (wie dieses Programm) und bauen unsere Argumentation darauf auf. Ein elegantes Beispiel, was durch Exceptions noch eleganter wird, ist wesentlich ueberzeugender.)

    Beispiel gefällig?

    Nehmen wir mal an, eine Klasse alloziert mehrere Daten, die möglichst noch aufeinander aufbauen. Der Konstruktor muss dabei eine konsistente Klasse hinterlassen.

    Mit RAII und Exceptions, sähe dies vielleicht wie folgt aus:

    // Seien a-c Smartpointer)
    Bar::Bar()
    :  a(new A()),
       b(new B(a),
       c(new C(a, b))
    {
    }
    

    Anschließend ist entweder die Klasse im konsistenten Zustand, oder die Konstruktion mittels Exception abgebrochen, und alle bis dahin allozierten Daten freigegeben. Viel Spaß mit deiner if-Schachtel-Orgie...

    cu André



  • knivil schrieb:

    Exceptions machen durchaus Sinn ohne RAII.

    Ne, nicht wirklich. Schonmal Java Code gesehen?

    File f=null;
    try {
      f=new File();
    }
    catch(Exception e) {
    }
    finally {
      if(f!=null) f.close();
    }
    

    Exceptions ohne RAII sind nicht wirklich besser als Errorcodes.

    Denn sehen wir uns den obigen Code mit RAII an:

    using(File f=new File()) {
    }
    

    welcher code ist wohl besser?



  • RAII verstanden wird. Und nein, das lässt sich nicht sinnvoll mit if-Verzweigungen nachbauen

    Ich will RAII nicht mit if nachbauen. Du scheint mich missverstanden zu haben.

    Mit RAII & Exceptions

    Wuerdest du RAII ohne Exceptions zaehlen lassen?

    Bar::Bar()
    :  a(new A()),
       b(new B(a),
       c(new C(a, b))
    {
    }
    

    Ich mag kein new in Initialisierungslisten (soll hier die nothrow-Variante sein), ich haette es so aehnlich gemacht (ungetestet):

    // seien a - c normale pointer :-)
    Bar::Bar(): a(0), b(0),c(0), valid_(false)
    {
        bool b = true;
        b = b && (a = new A());
        b = b && (b = ...
        ...
        valid_ = b;
    }
    
    Bar::~Bar()
    {
        delete a;
        delete b;
        delete c;
    }
    
    bool Bar::valid() { return valid_; }
    

    Klar kannst du jetzt sagen: Was wenn Klasse C ebenfalls Speicher anfordert und im ungueltigen Zustand ist? Bei solch einer Programmstruktur machen Exceptions schon Sinn, aber es bleibt ein kuenstliches Beispiel. Ich wuerde das uebergeordnete Problem dann wahrscheinlich auf andere Weise loesen.

    @Shade@work: Ja, der Javacode ist wirklich haesslich.

    Ein anderer Gesichtspunkt ist auch, wenn ich z.B. in C++ shared-object (DLLs) fuer z.B. Matlab schreibe. Ich moechte nicht auf die Datenstrukturen wie std::map, Iteratoren oder vorgefertigte Algorithmen verzichten. So wird die Bibliothek in C++ geschrieben und mittels C-Funktionen gewrapt. Da sind Exceptions einfach fehl am Platz.

    PS: Man kann auch auf Exceptions verzichten ohne gleich in if-Orgien zu enden. Mir ist das bis jetzt geglueckt. So, what's the point?



  • knivil schrieb:

    Ich mag kein new in Initialisierungslisten, ich haette es so aehnlich gemacht (ungetestet):

    Und was wenn die initialisierung nicht mit new ist, sondern es eben resourcen wie zB dateien sind, die über den ctor initialisiert werden? Willst du dann default ctor aufrufe haben?

    Ich habe deinen code mal korrigiert.

    // seien a - c normale pointer :-)
    Bar::Bar(): a(0), b(0),c(0), valid_(false)
    {
        bool f = true;
        f = f && (a = new A());
        f = f && (b = new B());
        f = f && (c = new C());
        valid_ = f;
    }
    
    bool Bar::valid() { return valid_; }
    

    Naja, jetzt das ganze mit Exceptions:

    Bar::Bar(): a(new A()), b(new B()),c(new C())
    {
    }
    

    mhm.

    Welche Code ist besser?

    Bedenke: beide Varianten arbeiten mit RAII.

    PS: Man kann auch auf Exceptions verzichten ohne gleich in if-Orgien zu enden. Mir ist das bis jetzt geglueckt. So, what's the point?

    Der Punkt Horizont Erweiterung. Du baust bei trivialen Klassen deutlich mehr Code als ich. Und mein Code ist dennoch Fehlerresistenter.

    Das hat nichts damit zu tun ob ich jetzt besser programmieren kann oder nicht, sondern einfach mit moderner technik. c++ ist was fehlerbehandlung betrifft den meisten sprachen um welten voraus und es wäre schön wenn alle c++ programmierer das einsehen würden und modernen code schreiben würden.

    Bring mir deshalb bitte ein Beispiel wo du denkst dass dein error-flag ansatz sehr schön zu tragen kommt. und ich schreib dir den code moderner und schöner neu.

    was hältst du davon?
    das beispiel hier mit 3 resourcen die es zu initialisieren gibt ist zB ein guter anfang: man hat immer irgendwelche resourcen die man initialisieren muss.

    die moderne variante hat 0 zeilen fehlerbehandlung, dein code hat 6 zeilen.

    lässt sich beliebig skalieren das ganze 😉

    ich muss aber zugeben hier etwas missionarisch zu sein, da ich immer wieder solchen code wie deinen sehe und dann sehe wie die leute zu java oder dergleichen wechseln weil dort fehlerbehandlung bequemer ist. und das finde ich schade - da resourcen verwaltung in c++ eine sehr sehr schöne lösung bietet wie sie in anderen sprachen nur sehr selten angetroffen wird.

    nur leider kennen die wenigsten leute diese techniken 😞



  • audacia schrieb:

    Nachtrag:
    Gerade bin ich wieder über ein Stück Code gestolpert, das hervorragend demonstriert, warum Exceptions besser sind.
    http://blogs.msdn.com/oldnewthing/archive/2004/07/20/188696.aspx

    So was kann man aber auch mit labels/gotos lösen - soll zwar kein Argument ggn Exceptions sein, aber hier hatte ma wer im forum gezeigt, dass sowas doch nen ganz gutes anwendungsgebiet für label/goto ist ^^ (die einrückungsebenen entfallen halt)

    bb



  • Mal eine Frage zu Exceptions. Wenn ich eine verzweigtes Programm habe und dort zB. eine Klasse TextureManager vorkommt. (Ich nehme mal das bereits genannte Beispiel; das passt gut) Die Klasse hat eine Methode LoadAll oder Ähnliches. So, diese Funktion kann jetzt aus was für Gründen auch immer die fünfte Textur von meinetwegen zehn nicht laden und wirft eine Exception.

    Insgesamt haben wir aber nur eine zentrales Try-Catch-Konstrukt (das war ja eine positive Seite von Exceptions), dann springt das Programm ja dank der Exception aus dem kompletten Programmfluss und landet im Exception-Handler. Jetzt können wir ja schön den Fehler begutachten, da ja alle Informationen in der Exception-Klasse gespeichert sind, aber zurück in den Programmfluss kommen wir ja nicht. Dank RAII wird dann ja der Speicher aller bereits geladenen Texturen freigegeben werden und man müsste die Routine - oder schlimmstenfalls das halbe Programm - nochmal aufrufen und alle Texturen neuladen. Viel sinnvoller wäre es doch, wenn man direkt an dezentraler Stelle darauf reagieren könnte und somit ohne Exceptions.

    Oder sollte man diesen Fall gar nicht als Exception behandeln, sondern eher mit Rückgabewert oder Ähnliches? Immerhin soll der Benutzer der Engine (oder halt nur der Klasse) selbst entscheiden können, wie er darauf reagiert, ob er dann eine Default-Textur laden lassen will oder doch lieber das Programm usw. usf.

    Irgendwo habe ich hier noch einen Denkfehler drinne, denn so passt ist das ja nicht allzu nützlich, da man dadurch ja viel zu unflexibel wäre.



  • knivil schrieb:

    Wuerdest du RAII ohne Exceptions zaehlen lassen?

    Ich finde das RAII ohne Exceptions bei weiten nicht mehr den Nutzen hat, wie mit Exceptions.

    knivil schrieb:

    Ich mag kein new in Initialisierungslisten...

    Das ist deine Entscheidung, ich verwende wiederum gerade dort new um den Nötigen Code auf ein Minimum zu reduzieren. Weniger Code stellt auch weniger Fehlerquellen zur Verfügung, zudem hat meine Behandlung gegenüber deiner Variante IMHO ausschließlich Vorteile (bzw. nenne mir mal Nachteile).

    Vorteile:
    1. Keine unnötigen nachträglichen Zuweisungen.
    2. Im Fehlerfall wird die Konstruktion automatisch rückgängig gemacht.
    3. Gleichzeitige Reduzierung des benötigten Code und weniger Fehlerquellen.
    4. Das Objekt ist gültig, und Bedarf dazu keiner weiteren Behandlung von Außen wie Validierungsprüfungen. Einzig die Fehlerbehandlung muss einmal geschrieben werden - und zwar genau an der Stelle die darauf reagieren kann.
    5. Das ist aber nur die Kür: Ich spare mir zudem die Implementation des Destruktors.

    knivil schrieb:

    Klar kannst du jetzt sagen: Was wenn Klasse C ebenfalls Speicher anfordert und im ungueltigen Zustand ist? Bei solch einer Programmstruktur machen Exceptions schon Sinn, aber es bleibt ein kuenstliches Beispiel. Ich wuerde das uebergeordnete Problem dann wahrscheinlich auf andere Weise loesen.

    Mal ganz davon abgesehen das ein Code wie von dir gezeigt, mir in Projekten schon etliche Tage der Fehlersuche gekostet haben, und bei leibe kein künstliches Beispiel sind. Mein Ansatz hat aber noch einen weitere Vorteil:

    6. Ich muss den Code nicht umschreiben wenn ein Objekt das ich alloziere wiederum Speicher alloziert. Sondern habe eine saubere Form der "Transaktion" (Im Fehlerfall wird alles automatisch aufgeräumt, und eine Sonderbehandlung ist nur an einer Stelle nötig [Ein try/catch Block - sofern man den Fehler behandeln kann]).

    knivil schrieb:

    Ein anderer Gesichtspunkt ist auch, wenn ich z.B. in C++ shared-object (DLLs) fuer z.B. Matlab schreibe. Ich moechte nicht auf die Datenstrukturen wie std::map, Iteratoren oder vorgefertigte Algorithmen verzichten. So wird die Bibliothek in C++ geschrieben und mittels C-Funktionen gewrapt. Da sind Exceptions einfach fehl am Platz.

    Das ist die einzige Stelle, an der ich Exceptions "wrappe". Sprich, ich wandel in der Schnittstelle Exceptions durch Fehlercodes. Konkret verwende ich Fehlercodes nur und ausschließlich an C-Schnittstellen.

    knivil schrieb:

    PS: Man kann auch auf Exceptions verzichten ohne gleich in if-Orgien zu enden. Mir ist das bis jetzt geglueckt. So, what's the point?

    Also ich sehe in deinen Code schon einige ifs, die ich mir gänzlich spare. Mein Konstruktor besteht in meinen Codestil aus 6 Zeilen, deiner würde darin mindestens 12 + Benötigten Destruktor + Benötigte Validierungslogik kosten.

    Ich sehe in deinem Weg keinerlei Vorteile gegenüber Meinen. Zeig mir doch mal bitte ein wirklich guten Grund gegen meine Variante, oder nenn mir bitte auch einen wirklichen Nachteil, der die Vorteile überwiegt.

    Zudem musst du eh Exceptionhandling einsetzen, zumindest wenn du ernsthaft die STL verwendest.

    cu André
    P.S: Ohne dir nahe zu treten, erinnert mich bislang die Argumentation an meinen letzten Programmierchef. Dieser war sauer weil ich bei den selbstgeschriebenen Smartpointern im Falle eines NULL-Zugriffes eine Exception geworfen habe (mit Fehlermeldung zu welchen Templatetyp etc. um die Fehlersuche zu erleichtern). Ich habe lieber einen kontrollierten Absturz mit einer Fehlermeldung (um den Fehler suchen zu können), als eine Access Violation mit unkontrollierten Absturz.



  • issen1 schrieb:

    ...So, diese Funktion kann jetzt aus was für Gründen auch immer die fünfte Textur von meinetwegen zehn nicht laden und wirft eine Exception....

    Insgesamt haben wir aber nur eine zentrales Try-Catch-Konstrukt (das war ja eine positive Seite von Exceptions)...

    Falsch. Wir haben ein try/catch Konstrukt, an der Stelle die den Fehler behandeln kann, nicht ein zentrales. Insgesamt wird es mehrere try/catch-Blöcke in einer großen Anwendung geben, nichts desto trotz bei sauberer Programmierung deutlich weniger Codezeilen als eine Einzelbehandlung von Fehlercodes.

    Und nun denk nochmal über deinen restlichen Text nach 😉

    cu André



  • Letztendlich verstehe ich eure Punkte (auch in Bezug auf die missionarische Verpflichtung). Geht mir bei anderen Sachen aehnlich (bin nur weniger emotional). Zu meiner Herangehensweise: Ich versuche fehlerfreien Code abzuliefern. Auch ist der 6 Zeilen Umweg um Exceptions herum nicht schoen (aber auch nicht haesslich) und in der Implementation verborgen.

    Ich sehe in deinem Weg keinerlei Vorteile gegenüber Meinen.

    So fuer sich genommen ist deine Loesung wahrscheinlich besser. Ein Vorteil faellt mir aber noch ein: Ich traue meine Anwendern (, die die Funktion benutzen) manchmal nicht wirklich zu, mit den Exceptions richtig umzugehen.

    Jetzt können wir ja schön den Fehler begutachten, da ja alle Informationen in der Exception-Klasse gespeichert sind

    Fuer Debugging gibt es andere Moeglichkeiten, ich wuerde Exceptions nicht dafuer missbrauchen. Auch was deine Smartpointer-Exceptions betrifft, finde ich sie fuer die Fehlersuche ungeeignet. Ausnahme: assert, da es im Release dann automatisch verschwindet. Aber deswegen sauer zu werden, so emotional bin ich da nicht.



  • unskilled schrieb:

    So was kann man aber auch mit labels/gotos lösen - soll zwar kein Argument ggn Exceptions sein, aber hier hatte ma wer im forum gezeigt, dass sowas doch nen ganz gutes anwendungsgebiet für label/goto ist ^^ (die einrückungsebenen entfallen halt)

    Siehe meine Artikel 😉
    Aber es ist immer noch wahnsinn im vergleich zu exceptions.

    issen1 schrieb:

    Viel sinnvoller wäre es doch, wenn man direkt an dezentraler Stelle darauf reagieren könnte und somit ohne Exceptions.

    Kannst du mit Exceptions ja. Exceptions bietet die Moeglichkeit an Zentral auf Fehler zu reagieren, aber sie beschneiden nicht die Option auch lokal zu reagieren wenn es sinn macht. Meistens macht es wenig Sinn lokal zu reagieren, deshalb sind error codes ja so schlecht, weil ich immer lokal reagieren muss.

    mit exceptions reagiere ich prinzipiell an wenigen zentralen stellen auf die fehler und in besonderen situationen eben lokal.

    knivil schrieb:

    Ich versuche fehlerfreien Code abzuliefern. Auch ist der 6 Zeilen Umweg um Exceptions herum nicht schoen (aber auch nicht haesslich) und in der Implementation verborgen.

    Aber unnoetig und welchen vorteil bringt er dir?

    du baust dir die moeglichkeiten fuer mehr fehler ein, da du ja in dem fehlerbehandlungscode fehler machen koenntest und ein code review mit einer niedrigeren wahrscheinlichkeit fehler findet. natuerlich nicht um viel. der unterschied ist hier minimal. aber rechne das ganze jetzt auf millionen von zeilen auf. immer ein bisschen schlechter - das macht am ende dann doch etwas aus.

    So fuer sich genommen ist deine Loesung wahrscheinlich besser. Ein Vorteil faellt mir aber noch ein: Ich traue meine Anwendern (, die die Funktion benutzen) manchmal nicht wirklich zu, mit den Exceptions richtig umzugehen.

    Aber mit error codes?

    Das verstehe ich nicht.
    kleines beispiel:

    file f("datei.txt");
    while(!f.eof()) {
      f.read();
    }
    

    mit deiner variante haben wir eine endlosschleife gebaut wenn "datei.txt" nicht geoeffnet werden kann. mit der exception variante haben wir vermutlich das programm mit der meldung "datei.txt konnte nicht geoffnet werden" abgeschossen.

    inwiefern ist es leichter wenn fehler aus versehen ignoriert werden koennen?

    Fuer Debugging gibt es andere Moeglichkeiten, ich wuerde Exceptions nicht dafuer missbrauchen.

    Exceptions liefern dir diese infos gratis. ohne aufwand.

    natuerlich debugt man nicht mit ihnen, aber es ist halt schon praktisch wenn du zB wie in java eine exception bekommst, auf sie doppelt klickst und zu der stelle springst an der sie geworfen wurde. unheimlich zeitsparend.

    natuerlich helfen hier asserts auch. selbes prinzip.

    aber was interessant ist, du kannst fehlermeldunden an den user viel schoener gestalten wenn du exceptions hast. denn du kennst zB den datei namen der nicht gefunden wurde. den kennst du mit error codes nicht... zumindest nicht ohne weiteres - bei exceptions ist es gratis dabei.


Anmelden zum Antworten