Beispiel aus Exceptional C++



  • Hallo Leute!

    Ich bin gerade dabei Exceptional C++ zu lesen (btw: ein ziemlich gutes Buch ;)), nur leider bin ich an einem Punkt nicht Sutters Meinung...

    Es geht um Exception Sicherheit in einem kleinen Beispiel:
    Welche Variante ist die beste?
    Sutter schlaegt diese 2 vor:

    void foo(Employee e/*muss per value sein*/, String& r)
    {
      String result=e.First()+" "+e.Last();
      if(e.Title()=="CEO" || e.Salary() > 100000)
      {
        String message = result + " ist ueberbezahlt!";
        cout<<message;
      }
      r=result;
    }
    //Nr. 2:
    String foo(Employee e/*muss per value sein*/)
    {
      auto_ptr<String> result=new String(e.First()+" "+e.Last());
      if(e.Title()=="CEO" || e.Salary() > 100000)
      {
        String message = result + " ist ueberbezahlt!";
        cout<<message;
      }
      return result;
    }
    

    Er meint, das Nr. 2 die richtige Loesung waere.
    Denn bei Nr. 1 kann ja r=result; eine Exception ausloesen...

    Ich frage aber nun, warum geht folgendes nicht?

    void foo(Employee e/*muss per value sein*/, String& r)
    {
      r=e.First()+" "+e.Last();
      if(e.Title()=="CEO" || e.Salary() > 100000)
      {
        String message = result + " ist ueberbezahlt!";
        cout<<message;
      }
    }
    

    Wenn bei r=... eine Exception fliegt, dann passt alles.
    Exception geht nach aussen...

    Das einzige 'Problem' das ich sehe ist, dass uU cout<<message; fehlschlagen kann. dadurch haette aber r schon den richtigen Wert, die funktion waere aber fehlgeschlagen.

    Nur sehe ich hierbei nicht das Problem...
    Sobald eine Exception fliegt ist die Funktion fehlgeschlagen und der 'return value' ist undefiniert...

    Meine Version wuerde mir den auto_ptr sparen und somit exakt 1 copy CTor und einen DTor, sowie einen op= wenn der return wart abgefragt wird...

    Eure Meinung dazu??



  • Hallo,
    soweit ich das sehe, geht es hier um die strenge Exceptiongarantie und Seiteneffekte.
    Damit eine Funktion streng Exceptionsicher ist, müssen entweder alle Seiteneffekte komplett oder gar nicht stattfinden.
    In deiner Lösung kann aber Seiteneffekt 1 (also das Zurückgeben des Namens) stattfinden, obwohl der 2. Seiteneffekt (nämlich die Erstellung und Ausgabe des Message-Strings) fehlschlägt.
    Dies mag in diesem Beispiel egal sein, es gibt aber sicher Beispiele wo es nicht egal ist. Den Punkt den Sutter hier zeigen möchte, ist IMHO, dass eine Funktion die mehr als eine Aufgabe zu erfüllen hat nicht generell streng exceptionsicher gemacht werden kann.

    Btw. Die Zeile

    auto_ptr<String> result=new String(e.First()+" "+e.Last());
    

    ist quatsch und dürfte sich nicht kompilieren lassen.
    Richtig wäre:

    auto_ptr<String> result(new String(e.First()+" "+e.Last()));
    

    Schließlich ist auto_ptrs Umwandlungsctor explicit.

    [ Dieser Beitrag wurde am 26.05.2002 um 22:28 Uhr von HumeSikkins editiert. ]



  • @Hume:
    da ich mich mit auto_ptr noch nie naeher befasst habe, glaube ich dir mal. Obwohl in meiner Ausgabe von Exceptional C++ '...= new String(...' steht...

    was den Seiteneffekt angeht:
    Der ist mir durchaus klar, nur verstehe ich nicht, warum er nicht stattfinden darf.
    IMHO sind sowieso alle return werte undefiniert wenn eine exception fliegt.

    Aber OK, wenns so sein muss...

    Ich bleib bei meiner Version, so schlecht finde ich sie ja nicht.

    wenn ich aber genau ueberlege, wie siehst hiermit aus?

    void foo(Employee e/*muss per value sein*/, String& r)
    {
      String result =e.First()+" "+e.Last();
      if(e.Title()=="CEO" || e.Salary() > 100000)
      {
        String message = result + " ist ueberbezahlt!";
        cout<<message;
      }
      swap(result,r);
    }
    

    Soweit ich aus anderen Kapiteln des Buches entnommen habe, soll bzw. muss ein Swap eine no-throw() garantie haben...

    das wuerde mir dann zwar nichts besonderes sparen, ich waere aber den auto_ptr los...



  • @Shade
    Die auto_ptr Zeile in Sutters Buch ist einfach falsch. Ich habe ihm auch gerade eine Mail geschrieben 😉

    Zum Thema swap:
    Das geht natürlich nur, wenn du entweder
    a) Zugriff auf die Implementation der Klasse String hast und eine Swap-Funktion schreiben kannst oder wenn du
    b) die Klasse std::string und dessen Methode swap verwendest

    Die Funktion std::swap sieht ja in etwa so aus:

    template <class T>
    void Swap(T& t1, T& t2)
    {
        T Temp(t1);
        t1 = t2;
        t2 = Temp;
    }
    

    Wenn du da jetzt zwei Objekte eines Stringtyps da reingibst, hat die natürlich keine no-throw-Garantie.

    Für den Fall, dass a) oder b) gilt, sehe ich jetzt ehrlich gesagt auch kein Problem in deiner Version.

    void Foo(std::string& r)
    {
        std::string R ("Hallo");
        // ...
        R.swap(r);
    }
    

    Das erscheint mir eine durchaus mögliche und elegante Lösung zu sein.

    [ Dieser Beitrag wurde am 26.05.2002 um 23:47 Uhr von HumeSikkins editiert. ]



  • vieleicht ein wenig OT aber erwähnes wert für die stillen mittlesser, zu den buch gibt eine 50 seite lesse probe ( 😮 das ist ein 1/5 des buches) http://www.c-plusplus.net/titel_17.htm

    [ Dieser Beitrag wurde am 27.05.2002 um 01:05 Uhr von Dimah editiert. ]



  • Mir scheint, aus dem Exception-Schlamassel kommt man am saubersten raus, wenn man überhaupt alle eigenen Klassen mit nem swap ausstattet und auch swappt, was das Zeug hält.
    Ich war von dem Buch ein wenig enttäuscht. Ok, auf die Exceptionsicherheit ist er sehr eindringlich eingegangen. Aber sonst war irgendwie nix interessantes drin.



  • @volkard
    Wann hast du es denn gelesen? Warst du da schon der jetztige Guru-Volkard?

    Also ich muss sagen, dass Exceptional und More Exceptional C++ mir riesig viel geholfen haben. Ich schaue da nach wie vor jeden zweiten Tag rein. Im EC++ gefallen mir neben dem Kapitel über Exceptionsicherheit besonders die Kapitel über "Class Design and Inheritance", "Compiler Firewalls" und "Name Lookup, Namespaces and the Interface Principle". Aber wie gesagt, eigentlich hat mir das Lesen jedes einzelnen Items spass gemacht und mich ein wenig voran gebracht.

    So ist das mit den Büchern. Der eine ist begeistert, der andere enttäuscht 🙂



  • Osterferien 2002.
    Nee, was mich störte, war, daß es nicht gerade Richtungen vorgibt, sondern so winzige Details durchgeht, daß ich die überhaupt nicht wissen will. Details kann ich, sofern Problembewußtsein vorhanden, jederzeit selber ausknobeln (bzw. in fremdem Code finden und als allgeimne Lösung erkennen).
    Name Lookup ist so ein Ding, das ich nicht wissen will,denn wenn es so kompliziert ist, dann ist da die Sprache kaputt und ich wart auf ne bessere.
    So ist das mit den Büchern. Der eine ist begeistert, der andere enttäuscht 🙂



  • Danke!



  • Der Thread ist eine wieder erweckte Leiche. Bitte auf's Datum achten.


Anmelden zum Antworten