Frage zu return-Ergebnissen



  • 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_o

    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?

    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_o

    ich 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 zurueckgeben

    das 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 🙂


Anmelden zum Antworten