Frage zu return-Ergebnissen
-
Nö, die Klasse in der Fehler auftreten können erbt nicht vom Interface, sondern du leitest die Klasse vom Interface ab, die den Fehler behandeln soll.
-
Anfänger1 schrieb:
Das mit den Exceptions ist ein bisschen problematisch, da ich in meiner Klasse mehere Threads habe, und es anscheinend nicht möglich ist Exceptions weiterzugeben.
Nein, ist kein bisschen Problematisch. Denn der Thread muss ja irgendwo enden und dann muss er irgendeine notification an den rest der anwendung abgeben. und genau hier setzt du mit exceptions an. Die exception wird hier gefangen und du gibst die entsprechende notification weiter.
-
Shade Of Mine schrieb:
raps schrieb:
man sollte bedenken dass exceptions sehr langsam sind.
Deshalb 64Bit verwenden
indem du den teufel gegen den belzebub tauscht, aenderst du nicht viel am overhead. hast halt wenig heavy weight statt viel lightweight work.
Die Performance im Fehlerfall ist komplett irrelevant. Denn wenn du exception wirfst wenn es sich um keinen Fehler handelt, hast du etwas falsch gemacht (zB dein dynamic_cast beispiel). Und wenn du dauernd fehler in der anwendung hast, dann ist die performance wohl eh erstmal uninteressant :p
Da stimme ich zu, deswegen sagte ich, dass man moeglichst weit ohne exception werfen kommen sollte und auch dinge die man als fehler ansehen koennte, als warning rausstreamt und trotzdem weitermacht. performance der anwendung ist die eine sache die mit exceptions leidet, performance der entwicklung die andere.
Ich habe in einer umgebung mit ca 50leuten mit einer lib gearbeitet die sich sehr "OOP" schimpfte, natuerlich mit exceptions bei allen moeglichen dingen. Fehlte eine datei die man oeffnen wollte -> exception, format von etwas war falsch -> exception. objekttyp von etwas war falsch -> exception...
das resultat davon war extreme unproduktivitaet, man fixte oft fehler fuer fehler bis man endlich arbeiten konnte (und die die nichts fixen konnten, warteten).die alternative mit der ich jetzt arbeite hat nicht eine exception die geworfen werden wuerde. fuer alles was schiefgeht gibt es fallbacks und die streamen in den log.
Man koennte zwar meinen, dass sowas fehler verbirgt und anarchie-maessig laeuft, aber genau das gegenteil ist der fall. Die leute arbeiten sehr produktiv und jede warning wird beseitigt, die leute sind auch weniger gehemt weit mehr warnings zu streamen als man exceptions werfen wuerde, weil man weiss, dass es niemanden behindert, sondern eher hilft.ich finde exceptions sollte man wirklich nur schmeissen wenn man sich garnicht mehr anders zu helfen weiss, also nicht bei "errors", sondern wirklich bei blockierenden ereignissen. Passiert bei unserer lib nur vom system aus, z.b. access violation.
In dem fall sollte man dann auch (wie bei java ueblich ;)), den kompletten callstack und wenn moeglich den memory dump ausgeben.
Man sollte soviel informationen wie moeglich von einer exception erhalten, denn wie das wort schon sagt, ist es eine ausnahme, somit sollte sie eigentlich nie passieren und ist somit auch nur aufwendig reproduzierbar.my2cent
-
raps schrieb:
indem du den teufel gegen den belzebub tauscht, aenderst du nicht viel am overhead. hast halt wenig heavy weight statt viel lightweight work.
Du reduzierst im 64bit modus den runtime overhead von exceptions wenn sie nicht fliegen auf quasi 0 - da du nur noch in einer map nachsehen musst was zu tun ist und der key der IP ist...
dh, das bereits ein if zur fehlerbehandlung teurer waere als 1000 moegliche exceptions. viel besser wirds nicht mehr gehen. denn innerhalb der funktion muss, sofern es kein catch gibt, NICHTS gemacht werden, nada.
Da stimme ich zu, deswegen sagte ich, dass man moeglichst weit ohne exception werfen kommen sollte und auch dinge die man als fehler ansehen koennte, als warning rausstreamt und trotzdem weitermacht. performance der anwendung ist die eine sache die mit exceptions leidet, performance der entwicklung die andere.
was fuer fehler sind denn warnungen?
Ich habe in einer umgebung mit ca 50leuten mit einer lib gearbeitet die sich sehr "OOP" schimpfte, natuerlich mit exceptions bei allen moeglichen dingen. Fehlte eine datei die man oeffnen wollte -> exception, format von etwas war falsch -> exception. objekttyp von etwas war falsch -> exception...
das resultat davon war extreme unproduktivitaet, man fixte oft fehler fuer fehler bis man endlich arbeiten konnte (und die die nichts fixen konnten, warteten).Ja ich hab auch schon schlechten java und C code gesehen.
ich hab sogar mal schlechten bf code gesehen O_odie alternative mit der ich jetzt arbeite hat nicht eine exception die geworfen werden wuerde. fuer alles was schiefgeht gibt es fallbacks und die streamen in den log.
der user will eine datei speichern, du kannst sie aber nicht speichern weil platte voll ist.
was dann?ich finde exceptions sollte man wirklich nur schmeissen wenn man sich garnicht mehr anders zu helfen weiss, also nicht bei "errors", sondern wirklich bei blockierenden ereignissen. Passiert bei unserer lib nur vom system aus, z.b. access violation.
definiere bitte was du fuer unterschiedliche fehlertypen kennst.
Ich kenne nur 2 Arten: fatale fehler (logik fehler) die nie auftreten duerfen (interne invarianten verletzt) -> assert. Dann kenne ich noch "normale" Fehler, wie eben zB festplatte voll (laufzeit fehler - koennen immer auftreten) und das wars. Was kennst du noch fuer Fehler? Am besten mit Beispiel.
-
Shade Of Mine schrieb:
raps schrieb:
indem du den teufel gegen den belzebub tauscht, aenderst du nicht viel am overhead. hast halt wenig heavy weight statt viel lightweight work.
Du reduzierst im 64bit modus den runtime overhead von exceptions wenn sie nicht fliegen auf quasi 0 - da du nur noch in einer map nachsehen musst was zu tun ist und der key der IP ist...
dh, das bereits ein if zur fehlerbehandlung teurer waere als 1000 moegliche exceptions. viel besser wirds nicht mehr gehen. denn innerhalb der funktion muss, sofern es kein catch gibt, NICHTS gemacht werden, nada.
wir sind uns doch einig drueber dass wir die wahl zwischen if oder catch haben, oder? (klingt so als ob du sagst if waere langsam, aber catch muss man nicht einbauen).
die if abfrage kostet dich weit weniger als ein catch block.Da stimme ich zu, deswegen sagte ich, dass man moeglichst weit ohne exception werfen kommen sollte und auch dinge die man als fehler ansehen koennte, als warning rausstreamt und trotzdem weitermacht. performance der anwendung ist die eine sache die mit exceptions leidet, performance der entwicklung die andere.
was fuer fehler sind denn warnungen?
ich meine nicht fehler==warnungen, ich meine fehler kann man behandeln und dann muss man nur noch eine warnung ausgeben.
z.b.
bilddatei nicht gefunden -> dummy bild
config nicht gefunden -> default settings
out of memory -> alte resourcen freigeben und nochmal versuchen
sound dll nicht geladen -> dummy interface zurueckgeben
etc.Ich habe in einer umgebung mit ca 50leuten mit einer lib gearbeitet die sich sehr "OOP" schimpfte, natuerlich mit exceptions bei allen moeglichen dingen. Fehlte eine datei die man oeffnen wollte -> exception, format von etwas war falsch -> exception. objekttyp von etwas war falsch -> exception...
das resultat davon war extreme unproduktivitaet, man fixte oft fehler fuer fehler bis man endlich arbeiten konnte (und die die nichts fixen konnten, warteten).Ja ich hab auch schon schlechten java und C code gesehen.
ich hab sogar mal schlechten bf code gesehen O_oich spreche eher von der designentscheidung der menge der exception, nicht so sehr vom code an sich;)
die alternative mit der ich jetzt arbeite hat nicht eine exception die geworfen werden wuerde. fuer alles was schiefgeht gibt es fallbacks und die streamen in den log.
der user will eine datei speichern, du kannst sie aber nicht speichern weil platte voll ist.
was dann?gut: du gibst eine warnung aus beim ersten mal und danach nur noch ins log, und laeufst weiter als waere nichts (programtechnisch: in den error-stream eine warnung "Wurde nicht gespeichert" ausgeben und return FAIL;)
schlecht 1: du wirfst ne exception die irgendwo gefangen wird und dem user sagt "kritischer fehler: 'datei konnte nicht gespeichert werden' program wird beendet"
schlecht 2: du gibst bei jedem versuch zu speichern (z.b. eine sequenz von bildern) immer wieder "geht nicht" aus.ich finde exceptions sollte man wirklich nur schmeissen wenn man sich garnicht mehr anders zu helfen weiss, also nicht bei "errors", sondern wirklich bei blockierenden ereignissen. Passiert bei unserer lib nur vom system aus, z.b. access violation.
definiere bitte was du fuer unterschiedliche fehlertypen kennst.
hab ich schon, errors die zwar passieren, aber kein grund sind den programmfluss zu unterbrechen. exceptional errors, fehler von denen man nicht erwarten wuerde dass sie passieren und sie deswegen "ausnahme fehler" sind.
wenn also eine funktion etwas macht und man weiss dass diese aktion fehlschlagen kann, dann ist es keine ausnahme/exception. um dein beispiel von "platte ist voll" aufzugreifen, fopen wirft keine exception wenn eine datei nicht geoeffnet werden konnte. du hast einen return-wert, der dir einen der moeglichen resultate der aktion zurueckliefert. genau so sollte das programm dann auch weiter verlaufen. dein serializer wird initialisiert, er gibt dir ein fehler zurueck und du gibst ne warnung an den user aus oder in ein log, dass nicht gespeichert wird.
(ja, ich weiss, fstreams koennen auch exceptions werfen, deswegen war mein beispiel mit fopen)
Ich kenne nur 2 Arten: fatale fehler (logik fehler) die nie auftreten duerfen (interne invarianten verletzt) -> assert. Dann kenne ich noch "normale" Fehler, wie eben zB festplatte voll (laufzeit fehler - koennen immer auftreten) und das wars. Was kennst du noch fuer Fehler? Am besten mit Beispiel.
fehler die man erwartet hat und behandeln kann
foo(void* bar) { assert(bar); if(!bar) { ... return...; } . . . } //or save(const char* foo) { if(!open(foo)) { .... return .... ; } write write close
ausnahmefehler die man nicht erwartet hat
foo(float bar) { return bar*bar; //float exception: overflow, oder NAN... } bar::foo() { return member; //this is 0 or invalid }
zu ausnahmefehlern wuerde ich auch zaehlen wenn man von einer verwendeten funktion/bibliothek keine chance hat den fehler zu behandeln
HalfSize() { myVector.resize(myVector.size()/2); //out of mem, could not allocate destination buffer }
entsprechend schreib ich kein try-catch block unmittelbar um diese stellen, denn ich weiss dass es in 99.99% der laufzeit bloedsinn waere, aber ich weiss auch, dass es in ausnahmefaellen passiert.
-
rapso schrieb:
die if abfrage kostet dich weit weniger als ein catch block.
Nur wenn eine exception fliegt. Wenn keine fliegt kostet das if deutlich mehr (und du brauchst deutlich mehr ifs als catches)
bilddatei nicht gefunden -> dummy bild
config nicht gefunden -> default settings
out of memory -> alte resourcen freigeben und nochmal versuchen
sound dll nicht geladen -> dummy interface zurueckgeben
etc.Wenn es ein fallback gibt, ist es kein Fehler.
weil dann mache ich ein if(exists) und öffne nur wenn die datei da ist.wenn also eine funktion etwas macht und man weiss dass diese aktion fehlschlagen kann, dann ist es keine ausnahme/exception. um dein beispiel von "platte ist voll" aufzugreifen, fopen wirft keine exception wenn eine datei nicht geoeffnet werden konnte. du hast einen return-wert, der dir einen der moeglichen resultate der aktion zurueckliefert. genau so sollte das programm dann auch weiter verlaufen. dein serializer wird initialisiert, er gibt dir ein fehler zurueck und du gibst ne warnung an den user aus oder in ein log, dass nicht gespeichert wird.
Das sehe ich komplett anders.
Der User hat hier darauf hingewiesen zu werden dass seine Daten nicht gespeichert werden - man kann ja nicht einfach die daten des users wegwerfen...vl muss er ja auch nur ein anderes volume auswählen...
-
bilddatei nicht gefunden -> dummy bild
config nicht gefunden -> default settings
sound dll nicht geladen -> dummy interface zurueckgebendas sind fallbacks die du in deiner APPLIKATION einbauen kannst, wenn du magst, die aber ganz sicher nichts in einer library verloren haben die z.b. blider lädt! die library hat gefälligst in diesen fällen eine exception zu werfen, die du fängst, und dann dein dummy bild zurückgibst.
out of memory -> alte resourcen freigeben und nochmal versuchen
ist nur in den seltensten fällen möglich, aber ja. dafür gibt's ja extra hooks in denen du das erledigen kannst.
-
Anfänger1 schrieb:
Soweit ich das verstanden habe wird ein Programm nachdem eine Exception geworfen wird beendet.
Nicht wenn Du die Exception fängst.
Anfänger1 schrieb:
Und genau das kann ich nicht brauchen wenn der Fehler durch ein einfaches neustarten des Threads behoben werden kann.
Eine Exception kann nur von dem Thread gefangen werden der sie ausgelöst hat. Hast Du mehrere Threads, kann das Exception Handling allerdings etwas knifflig werden.
-
raps schrieb:
Ich habe in einer umgebung mit ca 50leuten mit einer lib gearbeitet die sich sehr "OOP" schimpfte, natuerlich mit exceptions bei allen moeglichen dingen. Fehlte eine datei die man oeffnen wollte -> exception, format von etwas war falsch -> exception. objekttyp von etwas war falsch -> exception...
das resultat davon war extreme unproduktivitaet, man fixte oft fehler fuer fehler bis man endlich arbeiten konnte (und die die nichts fixen konnten, warteten).Wo ist der Produktivitaetsunterschied zwischen:
try { open_file(...); }catch (FileNotFoundError& e) { load_default_file(); }
und
if (!open_file(...)) load_default_file();
-
Blue-Tiger schrieb:
Wo ist der Produktivitaetsunterschied zwischen:
1. Variante ist langsamer wenn ein fehler auftritt und schneller wenn keiner auftritt.
Aber eine schönere Variante ist:
DefaultFile file("/foo/bar", "/foo/default");
das schöne hier ist nämlich dass 1. die funktionalität gekapselt ist und 2. DefaultFile fstat oder dergleichen verwenden kann und das wird ja gecacht. Wir sind im fehlerfall also am schnellsten und im fall dass es /foo/bar gibt, immer noch gleich schnell