C zu C++ - Einfacherer Übergang?



  • namespace invader schrieb:

    Damit RAII das Problem löst, muss man aber Freigaben in Destruktoren verpacken (obwohl das in manchen Fällen gar nicht sinnvoll ist) und sich mit Smart Pointern rumschlagen (die nun wirklich ein hässlicher Workaround sind).

    Das ist keineswegs der Fall. Im Destruktor ist die Resourcenfreigabe schon an der richtigen Stelle, man muß sich natürlich Gedanken über die Lebensdauer des Objektes machen. Bei vielen Java Programmierern unterbleibt das - mit fatalen Konsequenzen.

    namespace invader schrieb:

    In Java wird das meiste Ressourcenhandling automatisch vom GC erschlagen,

    Inkorrekt, nur Speicher läßt sich damit verwalten.

    namespace invader schrieb:

    und für den Rest gibt es mit finally eine einfache und klare Lösung.

    Wie schreiben C Programmierer "… gibt es mit free eine einfache und klare Lösung" - lächerlich, da es unnötige Coderedumdanz und eine hohe Fehleranfälligkeit darstellt. Mit der Einführung des GC in Sprachen, meine erste GC Sprache war Oberon-2, wurde das Problem für Arbeitsspeicher gelöst, aber auch nur für Arbeitsspeicher. Alle anderen Resourcen muß man auch weiterhin händisch verwalten, und im Falle von Java muß man N finally Blöcke schreiben. Nervig, überflüssig, fehleranfällig. Dann lieber das Problem 1 mal in der Klasse lösen und nicht N mal bei der Nutzung der Klasse.

    Über die Lebensdauer der Exemplare einer Klasse muß sich der Nutzer einer Klasse immer Gedanken mache, egal ob es Smalltalk, CLOS, Java, C++ oder was auch immer ist.

    namespace invader schrieb:

    Vor allem kann man mit finally auch für andere, die den Code später lesen, klar ausdrücken, dass dort Ressourcen freigegeben werden. Bei RAII-Frickeleien, eventuell auch mit zusätzlichen Scopes nur zu dem Zweck, ist das nicht so einfach verständlich.

    Ach und bei GC soll das ganze auf einmal anders ablaufen? Entscheide dich mal für ein Vorgehen. Entweder ist die manuelle Freigabe von Resourcen schlecht, dann ist sie das immer, oder sie ist es nicht, dann solltest du auch keine Probleme mit malloc und free haben.

    namespace invader schrieb:

    … vor allem Zeiger die beliebig überall hin zeigen können.

    Java krankt fast an dem gleichen Problem, Nullpointer Exceptions sind bei Java allgegenwertig, also muß man auch mit Java aufpassen, daß Zeiger (Referenzen sind ganz banale Zeiger, wie man sie von Pascal kennt) nicht in Nirwana weisen. Java kennt lediglich keine Pointerarithmetik, auf die man in vielen Sprachen ohne GC ebenfalls verzichtet hat: Pascal, Modula-II, Ada, Fortran, …



  • rüdiger schrieb:

    Was ich immer sehr lustig finde, dass so getan wird als sei Exceptionsicherheit ein exklusives Problem von C++. Dabei ist es ein Problem in jeder Sprache mit Exceptions. In C++ ist das Problem natürlich offensichtlicher, weil man in er Regel keinen GC verwendet.

    Bei C++ hast du halt 100 mal soviel Dinge, bei denen du eigentlich auf Exceptionsicherheit achten müsstest. Aber wer verwendet denn schon Exceptions in C++?

    RAII finde ich eigentlich ziemlich genial. Ich hab noch keine bessere Methode gesehen, um Files wieder zu schließen oder ein Mutex wieder frei zu geben.

    Was wirklich nervt an C++ ist, dass es nie eine vernünftige Standard Library mit ausreichendem Funktionsumfang hatte. Jetzt hat fast jede Library ihren eigenen String, eigene Thread usw. Dieses ganze konvertieren und zusammenfummeln von Libraries die nicht schön zusammen passen, bremst die Entwicklungsgeschindigkeit ungemein.



  • ort schreiben schrieb:

    RAII finde ich eigentlich ziemlich genial. Ich hab noch keine bessere Methode gesehen, um Files wieder zu schließen oder ein Mutex wieder frei zu geben.

    Ist es nicht. Ich möchte garnicht erst wissen, wie viele C++ Programme aus Unachtsamkeit ein File einige hundert mal öffnen und schließen, obwohl jeweils eine Operation genügt hätte.
    Zu Mutexen: Mutex-Freigabe sollte so früh wie möglich erfolgen und nicht erst am Ende des Scopes. Man kann sich natürlich so behelfen:

    void f()
    {
      {
        Mutex lock;
        do_something_that_is_not_thread_safe();
      } // <-- unlock!
      do_other_stuff();
      do_more_stuff();
    }
    

    Aber das ist häßlicher und unituitiver als eine manuelle Freigabe mittels einer simplen Unlock-Funktion.

    RAII ist typisch für C++ insgeamt: man erfindet ein, auf den ersten Blick, tolles Feature, baut es sofort in die Sprache ein und schaltet dann sein Gehirn aus. 🙄



  • RAII stinkt schrieb:

    Zu Mutexen: Mutex-Freigabe sollte so früh wie möglich erfolgen und nicht erst am Ende des Scopes. Man kann sich natürlich so behelfen:

    void f()
    {
      {
        Mutex lock;
        do_something_that_is_not_thread_safe();
      } // <-- unlock!
      do_other_stuff();
      do_more_stuff();
    }
    

    Aber das ist häßlicher und unituitiver als eine manuelle Freigabe mittels einer simplen Unlock-Funktion.

    RAII ist typisch für C++ insgeamt: man erfindet ein, auf den ersten Blick, tolles Feature, baut es sofort in die Sprache ein und schaltet dann sein Gehirn aus. 🙄

    Ja, man kann sein Hirn ausschalten und es so machen, oder einfach in do_something_that_is_not_thread_safe() locken.



  • Die Java versionen sehen meisten viel besser aus.

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


  • ja schrieb:

    RAII stinkt schrieb:

    Zu Mutexen: Mutex-Freigabe sollte so früh wie möglich erfolgen und nicht erst am Ende des Scopes. Man kann sich natürlich so behelfen:

    void f()
    {
      {
        Mutex lock;
        do_something_that_is_not_thread_safe();
      } // <-- unlock!
      do_other_stuff();
      do_more_stuff();
    }
    

    Aber das ist häßlicher und unituitiver als eine manuelle Freigabe mittels einer simplen Unlock-Funktion.

    RAII ist typisch für C++ insgeamt: man erfindet ein, auf den ersten Blick, tolles Feature, baut es sofort in die Sprache ein und schaltet dann sein Gehirn aus. 🙄

    Ja, man kann sein Hirn ausschalten und es so machen, oder einfach in do_something_that_is_not_thread_safe() locken.

    Vorausgesetzt Du hast Zugriff auf die Interna dieser Funktion. Und selbst wenn, was machst Du, wenn ein Lock in do_something_that_is_not_thread_safe() nicht immer erwünscht ist, oder in den Lock von f() noch anderer Code hinein muß? RAII ist keine generelle Lösung für Resource Allocation (was leider immer wieder propagiert wird), sondern ein halbdurchdachte Krücke, die schlechten Code erst möglich macht 😞



  • RAII really stinks! schrieb:

    Vorausgesetzt Du hast Zugriff auf die Interna dieser Funktion. Und selbst wenn, was machst Du, wenn ein Lock in do_something_that_is_not_thread_safe() nicht immer erwünscht ist, oder in den Lock von f() noch anderer Code hinein muß?

    Wenn du willst, kannst du immer noch das Zeugs das gelockt werden muss in ne 2. Funktion stecken. Und was ist an nem Scope mit Klammer so schlimm? Mit try{}finally{} machst du auch immer nen scope auf und zusätzlich hast du ne Menge Code duplication, try - lock - finally - unlock immer und immer wieder.

    Dein einziges Argument war bis jetzt, dass du es unleserlich findest und so ein Schwachsinn, dass man wegen RAII nicht merken würde, wenn man ein File öffnet.

    RAII ist keine generelle Lösung für Resource Allocation (was leider immer wieder propagiert wird), sondern ein halbdurchdachte Krücke, die schlechten Code erst möglich macht 😞

    Na, dann zeig mal was das mit RAII nicht geht.



  • ~john schrieb:

    Java krankt fast an dem gleichen Problem, Nullpointer Exceptions sind bei Java allgegenwertig, also muß man auch mit Java aufpassen, daß Zeiger (Referenzen sind ganz banale Zeiger, wie man sie von Pascal kennt) nicht in Nirwana weisen. Java kennt lediglich keine Pointerarithmetik, auf die man in vielen Sprachen ohne GC ebenfalls verzichtet hat: Pascal, Modula-II, Ada, Fortran, …

    Und wieder ist ein C/C++ Thread zu einem C++ ist misst, Java ist besser ausgeartet. Ich wollte nur klarstellen, dass in Java es keine Pointer gibt, es gibt Referenzen, und diese können nicht ins Nirwana zeigen. Sie können entweder Null sein oder ein Objekt referenzieren.

    Zu RAII mal eine Frage. Wie könnt ihr im Dtor externe Ressourcen freigeben? Z.B. wenn man ein File-Stream schließt, dann kann eine Ausnahme fliegen. Deswegen ist es ein wenig komplizierter (siehe Beispiel und Link). Der Dtor wirft also die Exception und dann stürzt das gesamte Programm ab.

    String file;
            FileInputStream stream = null;
            try {
                stream = new FileInputStream(file);
                stream.read();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    

    http://tutorials.jenkov.com/java-exception-handling/exception-handling-templates.html

    na schrieb:

    RAII really stinks! schrieb:

    Vorausgesetzt Du hast Zugriff auf die Interna dieser Funktion. Und selbst wenn, was machst Du, wenn ein Lock in do_something_that_is_not_thread_safe() nicht immer erwünscht ist, oder in den Lock von f() noch anderer Code hinein muß?

    Wenn du willst, kannst du immer noch das Zeugs das gelockt werden muss in ne 2. Funktion stecken. Und was ist an nem Scope mit Klammer so schlimm? Mit try{}finally{} machst du auch immer nen scope auf und zusätzlich hast du ne Menge Code duplication, try - lock - finally - unlock immer und immer wieder.

    Dein einziges Argument war bis jetzt, dass du es unleserlich findest und so ein Schwachsinn, dass man wegen RAII nicht merken würde, wenn man ein File öffnet.

    RAII ist keine generelle Lösung für Resource Allocation (was leider immer wieder propagiert wird), sondern ein halbdurchdachte Krücke, die schlechten Code erst möglich macht 😞

    Na, dann zeig mal was das mit RAII nicht geht.

    Bei dem leerem Block weiß man aber nicht was er macht. Ist der Mutex für RAII konzipiert? Was, wenn man einen anderen Mutex nimmt? Bei einem mutex.unlock() weiß man sofort was Sache ist und der Compiler meckert, wenn man einen Mutex nimmt, der sich anders unlock-en lässt.



  • DEvent schrieb:

    Z.B. wenn man ein File-Stream schließt, dann kann eine Ausnahme fliegen. ...

    String file;
            FileInputStream stream = null;
            try {
                stream = new FileInputStream(file);
                stream.read();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    

    Das hat mich schon immer interessiert, warum beim stream.close() eine Exception auftreten kann. Wie kann sowas passieren? Ist dann das File für immer offen, wenn nicht mal mehr das OS es schließen kann? Und was soll man in so einem Fall machen, außer e.printStackTrace()?



  • @DEvent
    Warum sollte man in einem Dtor keine Exception fangen können?

    ~foo() try {
      close(fh);
    }
    catch(...) {
      print_backtrace();
    }
    

    Hat vorallem den Vorteil, dass man den Code nur einmal zentral schreiben muss und nicht überall wo man eine Datei aufmacht.



  • DEvent schrieb:

    Zu RAII mal eine Frage. Wie könnt ihr im Dtor externe Ressourcen freigeben? Z.B. wenn man ein File-Stream schließt, dann kann eine Ausnahme fliegen. Deswegen ist es ein wenig komplizierter (siehe Beispiel und Link). Der Dtor wirft also die Exception und dann stürzt das gesamte Programm ab.

    Falls man etwas benutzt das beim Ressourcen freigeben eine Exception wirft ist man doch gerne eingeladen das ganze mit einem try {something();} catch (std::exception) {} abzufangen. Wenn etwas bei der Resourcenfreigabe scheitert kann man sowieso nicht mehr viel machen ausser es zu ignorieren. Auch wenn jetzt einige Idioten behaupten wollen ein catch-Block dürfe niemals leer sein, die sollen mir erklären was man machen soll wenn man beim Schließen eines File-Streams eine Exception kriegt. Bill Gates anrufen 🙂 ?



  • DEvent schrieb:

    ...

    RAII ist keine generelle Lösung für Resource Allocation (was leider immer wieder propagiert wird), sondern ein halbdurchdachte Krücke, die schlechten Code erst möglich macht 😞

    Na, dann zeig mal was das mit RAII nicht geht.

    Bei dem leerem Block weiß man aber nicht was er macht. Ist der Mutex für RAII konzipiert? Was, wenn man einen anderen Mutex nimmt? Bei einem mutex.unlock() weiß man sofort was Sache ist und der Compiler meckert, wenn man einen Mutex nimmt, der sich anders unlock-en lässt.

    Was soll das bedeuten? Das beispiel von "RAII stinkt" war sowieso falsch. Du verwendest beim Mutex einen Scoped-Lock der den Mutex lockt und unlockt, und nich der Mutex selber macht im Destruktor das unlock, was ja Quatsch wäre. IM Scoped-Lock kannst du auch was anderes als unlock im Destruktor implementieren.



  • DEvent schrieb:

    String file;
            FileInputStream stream = null;
            try {
                stream = new FileInputStream(file);
                stream.read();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    

    in C++ sieht es so aus:

    String file;
      FileInputStream stream(file);
      stream.read();
    

    maximal mit einem try catch drumherum um filenotfound zu fangen:

    try {
      String file;
      FileInputStream stream(file);
      stream.read();
    } catch(FileNotFound& e) {
      ...
    }
    

    da sieht RAII ja furchtbar aus, oder? 😉



  • DEvent schrieb:

    Und wieder ist ein C/C++ Thread zu einem C++ ist misst, Java ist besser ausgeartet.

    Was erwartest Du, wenn es immer die gleichen Einwürfe sind, bei Themen wo sie gar nicht hingehören?

    DEvent schrieb:

    Ich wollte nur klarstellen, dass in Java es keine Pointer gibt, es gibt Referenzen, und diese können nicht ins Nirwana zeigen. Sie können entweder Null sein oder ein Objekt referenzieren.

    Und das stimmt zu 100% mit den Zeigern aus Oberon-2 überein, und das ist älter als Java. Das geradezu starrköpfige Beharren der meisten Java-Nutzer Java hätte keine Zeiger ist ziemlich albern.

    String file;
            FileInputStream stream = null;
            try {
                stream = new FileInputStream(file);
                stream.read();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                if (stream != null) {
                    try {
                        stream.close();
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                }
            }
    

    Offensichtlich Bist Du der Meinung, daß Du das Problem innerhalb des finally-Blocks lösen kannst. Wenn dem so ist, läßt sich das Problem analog in einem Destruktor lösen. Da besteht keinerlei Unterschied.

    Unterschiede gibt es zwischen C++ und Java, wenn der finally-Block bzw. der Destruktor selbst Exceptions werfen darf. Dann kann beim Abarbeiten der Blöcke eine weitere Exeception auftreten. Chained Exceptions kennt C++ nicht, so daß man hier ganz schnell bei unexpected() landet. Ergo, ist es in C++ am besten Destruktoren grundsetzlich keine Exceptions werfen zu lassen. Eine globale Error-Queue löst das Problem meist zuverlässig.

    Und wenn man sich den vom Dir verlinkten Blog-Eintrag durchliest, weiß man warum finally reiner Code-Bloat ist, und dem Blog-Autoren ist das auch bewußt, sonst hätte er kaum diesen Eintrag verfaßt. Ergo tritt genau das auf, was seit Jahren aus der C++ Entwicklerlager an Java kritisiert wird.

    DEvent schrieb:

    Ist der Mutex für RAII konzipiert?

    Man muß schon die Klassen kennen, die man verwendet. Der Rest ist Gewöhnung. So wie Du mit dem Gebrauch von finally vertraut bist, ist es ein C++ Programmierer mit RAII.



  • OldManJava schrieb:

    Das hat mich schon immer interessiert, warum beim stream.close() eine Exception auftreten kann. Wie kann sowas passieren? Ist dann das File für immer offen, wenn nicht mal mehr das OS es schließen kann? Und was soll man in so einem Fall machen, außer e.printStackTrace()?

    weil evtl. erst beim schließen die daten geschrieben werden und dementsprechend auch erst dann ein fehler auftreten kann.

    Den Fall müsste man also genauso behandeln wie andere Fehler.



  • DrGreenthumb schrieb:

    OldManJava schrieb:

    Das hat mich schon immer interessiert, warum beim stream.close() eine Exception auftreten kann. Wie kann sowas passieren? Ist dann das File für immer offen, wenn nicht mal mehr das OS es schließen kann? Und was soll man in so einem Fall machen, außer e.printStackTrace()?

    weil evtl. erst beim schließen die daten geschrieben werden und dementsprechend auch erst dann ein fehler auftreten kann.

    Den Fall müsste man also genauso behandeln wie andere Fehler.

    In C++ indem man es ignoriert (oder in einer Log Datei schreibt). 🙄
    http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3

    Write a message to a log-file. Or call Aunt Tilda. But do not throw an exception!

    ~john schrieb:

    Offensichtlich Bist Du der Meinung, daß Du das Problem innerhalb des finally-Blocks lösen kannst. Wenn dem so ist, läßt sich das Problem analog in einem Destruktor lösen. Da besteht keinerlei Unterschied.

    Nö, da steht "TODO: Auto generated catch block". Es ist also auf meiner "TODO-Liste".

    Man kann einen neuen File Stream erstellen, der dann die Daten irgendwo anders hinschreibt. Oder man zeigt ein "Warning: Harddisk on fire" in einer GUI Anwendung. Das alles wollt ihr also in einen Dtor packen, in eine Klasse, die damit überhaupt nichts zu tun hat (MVC Model)? Oder irgendwie in einen global Zustand abspeichern, damit man irgendwie den Anwender informiert?

    Die Exception kann man weiterleiten (re-throw) zu einem Objekt, der was damit anfangen kann. Dafür sind die Exceptions da und das Weiterleiten ist essentieller Bestandteil von Exceptions. Da Dtors keine Exceptions werfen dürfen, muss man das in C++ irgendwie anders lösen.

    Es hat wohl seinen Grund wieso die Streams der STL nicht mit Exceptions arbeiteten und man eher wie in C programmiert:

    ifstream is;
      is.open ("test.txt");
      if ( (is.rdstate() & ifstream::failbit ) != 0 )
        cerr << "Error opening 'test.txt'\n";
      return 0;
    


  • Du kannst C++ fstreams auch so einstellen, dass sie Exceptions werfen und eine close Funktion gibt es auch.



  • DEvent schrieb:

    In C++ indem man es ignoriert (oder in einer Log Datei schreibt). 🙄
    http://www.parashift.com/c++-faq-lite/exceptions.html#faq-17.3

    Write a message to a log-file. Or call Aunt Tilda. But do not throw an exception!

    Was machst du in Java? Realistisch betrachtet.

    Denken wir uns was triviales aus. Wir haben 2 Dateien und kopieren von der einen in die andere Datei:

    FileInputStream src=null;
    FileInputStream trg=null;
    try {
      src=new FileInputStream(a);
      trg=new FileInputStream(b);
      copy(trg, src);
    } catch(...) {
      //whatever
    } finally {
      try {
        if(src!=null) {
          src.close();
        }
      } catch(Exception e) {
        //whatever
      } finally {
        try {
          if(trg!=null) {
            trg.close();
          }
        } catch(Exception e) {
            //whatever
        }
      }
    }
    

    Die beiden whatevers sind nun das Problem. Dass man bei dem Code augenkrebs bekommt und einem erstmal richtig schlecht wird, davon abgesehen.

    Wir muessen den Fehler jetzt irgendwie behandeln, aber es koennen ja auch 2 Fehler sein. Mehr als loggen ist da nicht wirklich drinnen. Denn wie koennen wir das nun an den caller uebergeben, dass wir einen fehler beim schliessen hatten? Bedenke dass wir uU nur 1 Datei jemals geoeffnet haben.

    FileInputStream src=null;
    FileInputStream trg=null;
    ExceptionList el = new ExceptionList();
    try {
      src=new FileInputStream(a);
      trg=new FileInputStream(b);
      copy(trg, src);
    } catch(Exception e) {
      el.add(e);
      throw el;
    } finally {
      try {
        if(src!=null) {
           src.close();
        }
      } catch(Exception e) {
        el.add(e);
        throw el;
      } finally {
        try {
          if(trg!=null) {
            trg.close();
          }
        } catch(Exception e) {
          el.add(e);
          throw el;
        }
      }
    }
    

    So kann man natuerlich auch mehrere Exception werfen, nur wird dann das fangen bloed 😉

    Effektiv gesehen ist jede Form von exceptions aus destruktoren ein hack. c++ verbietet es einfach um eine menge probleme zu umgehen. C++ bietet aber genug moeglichkeiten um dennoch den Fehler anzuzeigen - uU kann man ja eben doch eine exception werfen wenn man denn so will. oder signale verwenden oder sonstwas.

    aber egal was man macht: es ist genau wie in jeder anderen Sprache ein hack.

    Es hat wohl seinen Grund wieso die Streams der STL nicht mit Exceptions arbeiteten

    Ja. Und soll ich ihn dir verraten?
    Weil man keine exceptions erzwingen wollte. Alle funktionen in der C++ Library sind exception neutral (von wenigen Ausnahmen). Man wollte, gerade am Anfang der standardisierung nicht exceptions erzwingen als der support dafuer einfach nicht da war.

    deshalb kann man exceptions aktivieren und deaktivieren wie man es braucht.

    PS:
    ich hatte nen fehler im aufraeumcode. und das bei soetwas trivialem. haendisch resourcen aufraeumen ist einfach eine katastrophe...



  • Shade Of Mine schrieb:

    deshalb kann man exceptions aktivieren und deaktivieren wie man es braucht.

    Das blöde ist nur, dass man ohne Exceptions keine Möglichkeit hat, einen Konstruktor fehlschlagen zu lassen.

    Und auch wenn man keine Exceptions verwenden will, zwingt einen allein die Tatsache, dass es in C++ Exceptions gibt, trotzdem dazu, ständig darauf zu achten dass der Code den man schreibt Exception-safe ist. Man verschwendet also Zeit, nur um sich um Sprachfeatures zu kümmern, die man gar nicht nutzen will. Im Prinzip das selbe wie die Kopierkonstruktoren und Zuweisungsoperatoren, für die man ständig Zeit opfert obwohl man sie eigentlich gar nicht braucht.



  • namespace invader schrieb:

    Und auch wenn man keine Exceptions verwenden will, zwingt einen allein die Tatsache, dass es in C++ Exceptions gibt, trotzdem dazu, ständig darauf zu achten dass der Code den man schreibt Exception-safe ist.

    Die Standardbibliothek ist ziemlich defensiv, was Exceptions anbelangt. Wenn du selbst keine Exceptions und keine Bibliotheken mit Exceptions verwendest, kann also nicht viel passieren. Abgesehen davon ist Exceptionsicherheit fast gratis, wenn man RAII verwendet. Man muss ja nicht C in C++ programmieren.

    Ich weiss zwar nicht, wie oft das bereits erwähnt wurde, aber in anderen Programmiersprachen hat man das Problem ebenfalls. Nur Speicher wird einem aufgeräumt, andere Ressourcen muss man selbst sichern. Und gerade in Sprachen wie Java, die an jeder Ecke eine Exception werfen und mit finally zu manueller Freigabe zwingen, ist das nicht besonders lustig.

    namespace invader schrieb:

    Man verschwendet also Zeit, nur um sich um Sprachfeatures zu kümmern, die man gar nicht nutzen will. Im Prinzip das selbe wie die Kopierkonstruktoren und Zuweisungsoperatoren, für die man ständig Zeit opfert obwohl man sie eigentlich gar nicht braucht.

    Schön, dass du gerade ein Beispiel bringst, auf das das Gegenteil zutrifft. Kopierkonstruktoren und Zuweisungsoperatoren musst du in den wenigsten Fällen selbst implementieren – nämlich dann, wenn du eine spezifische Kopiersemantik möchtest. In den meisten Fällen tun aber die eingebauten Funktionen das Richtige.


Anmelden zum Antworten