Return mit magic Numbers oder nicht???



  • Hallo NG

    ich habe eine Stilfrage:

    Ist folgender Code besser

    bool checkValue(int value) {
      if ( 0 == value ) {
        return false;
      }
    
      return true;
    }
    

    oder folgender

    bool checkValue(int value) {
      bool result = true;
    
      if ( 0 == value ) {
        result = false;
      }
    
      return result;
    }
    

    Und warum ist welcher besser?

    Grüße M. Incani



  • Das ist beides unnötig kompliziert.

    bool checkValue(int value) {
      return value != 0;
    }
    


  • Das wollte ich jetzt nicht wissen. Das Beispiel war aus der Luft gegriffen.

    Gruß,
    M. Incani

    MFK schrieb:

    Das ist beides unnötig kompliziert.

    bool checkValue(int value) {
      return value != 0;
    }
    


  • Wo siehst du da Magic Numbers?
    true und false sind ganz siche keine Magic Numbers.

    Davon abgesehen ist dein Beispiel gerade deswegen vollkommen sinnlos weil es aus der Luft gegriffen ist, die Antwort von MFK daher passend.
    Liefere ein besseres Beispiel ab dann bekommst du bessere Antworten.



  • int sehr_schlecht() {
      int res;
      if(foo()) 
        res = bar();
      else {
        foobar();
        foobaz();
        res = baz();
      }
      return res;
    }
    
    int schlecht() {
      if(!foo()) {
        foobar();
        foobaz();
        return baz();
      } else {
        return bar();
      }
    }
    
    int gut() {
      if(foo()) 
        return bar();
    
      foobar();
      foobaz();
      return baz();
    }
    


  • Die Variante den Rückgabewert nicht hinauszuzögern finde ich auch besser. Mithilfe von RAII ist das sehr elegant zu handhaben.



  • Shade Of Mine schrieb:

    int sehr_schlecht()
    int schlecht()
    int gut()
    

    lässt sich das auch objektiv begründen?



  • knall der heuler schrieb:

    Shade Of Mine schrieb:

    int sehr_schlecht()
    int schlecht()
    int gut()
    

    lässt sich das auch objektiv begründen?

    Schau dir den Code der einzelnen Funktionen an, dann siehst du als normaler Programmierer sofort, dass die Struktur bei den ersten beiden kaum durchschaubar ist beim letzten Fall, aber sofort die unterschiedlichen Aktionen klar werden.



  • Hallo,

    so wie ich Dich verstehe, ist die letzte Lösung aus reiner Lesbarkeit die bessere Lösung. Ich hätte nun gedacht, zwecks Debuggen wäre es besser in den Funktionen zu sehen was sie ermitteln.

    Gruß,
    M. Incani

    Tippgeber schrieb:

    knall der heuler schrieb:

    Shade Of Mine schrieb:

    int sehr_schlecht()
    int schlecht()
    int gut()
    

    lässt sich das auch objektiv begründen?

    Schau dir den Code der einzelnen Funktionen an, dann siehst du als normaler Programmierer sofort, dass die Struktur bei den ersten beiden kaum durchschaubar ist beim letzten Fall, aber sofort die unterschiedlichen Aktionen klar werden.



  • Das Problem bei der Weitergabe von Rückgabewerten ist meist das dann ziemlich tiefe Verschachtelungen rauskommen können, um so länger die Funktion wird.

    Wobei das Verlassen von Funktionen mittendrin auch unübersichtlich sein kann. Je nach Komplexität der Funktion zumindest.



  • Deshalb dachte ich auch es wäre besser die ermittelten Ergebnisse in einer Variable zu speichern und dann am Ende die Variable zurück zu geben.

    Gruß,
    M. Incani

    Fellhuhn schrieb:

    Das Problem bei der Weitergabe von Rückgabewerten ist meist das dann ziemlich tiefe Verschachtelungen rauskommen können, um so länger die Funktion wird.

    Wobei das Verlassen von Funktionen mittendrin auch unübersichtlich sein kann. Je nach Komplexität der Funktion zumindest.



  • BlackPepper schrieb:

    Deshalb dachte ich auch es wäre besser die ermittelten Ergebnisse in einer Variable zu speichern und dann am Ende die Variable zurück zu geben.

    Nein, wir wollen nie Code so designen dass er leicht debugbar ist. Denn das hängt stark vom Debugger ab. Und es ist besser gleich fehlerfreien code zu schreiben.

    Deshalb nie ans debuggen denken beim code schreiben.

    Davon abgesehen bringt ein single-entry-single-exit fürs debuggen sowieso nichts.

    Single-Entry-Single-Exit erhöht aber immer die komplexität des Codes. Und das ist etwas dass wir nie nie nie wollen.



  • Hallo Shade Of Mine,

    Erst mal Danke für Deine Antwort. Das Single Entry Single Exit die Komplexität erhöht, hat mir in Deinem vorangegangenen Beispielen eingeleuchtet. Aber warum bringt das nichts beim Debuggen.

    double sum(double a, double b){
      return a + b;
    }
    
    double calc(double a, double b){
      return sum(a, b) * sum(a, b);
    }
    
    int main(int argc, char *argv[]){
     cout << "(a+b)^2=" << calc(2.0,3.0) << endl;
    }
    

    Hier würde ich doch einen Fehler erst in main sehen und nicht schon früher.

    Gruß max

    Shade Of Mine schrieb:

    BlackPepper schrieb:

    Deshalb dachte ich auch es wäre besser die ermittelten Ergebnisse in einer Variable zu speichern und dann am Ende die Variable zurück zu geben.

    Nein, wir wollen nie Code so designen dass er leicht debugbar ist. Denn das hängt stark vom Debugger ab. Und es ist besser gleich fehlerfreien code zu schreiben.

    Deshalb nie ans debuggen denken beim code schreiben.

    Davon abgesehen bringt ein single-entry-single-exit fürs debuggen sowieso nichts.

    Single-Entry-Single-Exit erhöht aber immer die komplexität des Codes. Und das ist etwas dass wir nie nie nie wollen.



  • Shade Of Mine schrieb:

    Und es ist besser gleich fehlerfreien code zu schreiben

    Eindeutig und ergänzend: ...und der gut lesbar (wegen Wartung) und überschaubar ist (Aber da sind wir uns wohl ohnehin einig).

    Mein letzter "Programmierchef" war ein Verfechter der "single-entry-single-exit" aus "Performancegründen" und der "Übersichtlichkeit". Letzteres war ohnehin hinfällig, wenn man sah wie seine Klassen teilweise 10000+ Codezeilen (ohne Kommentar) und Funktionen auch mal an den 1000 Zeilen kratzen. Ersteres soll wohl mal in den C++ Urzeiten tatsächlich gültigkeit gehabt haben, ist heutzutage aber gänzlich hinfällig (und wenn ich mir die Aussagen einiger im Forum anschaue sogar inzwischen eher das Gegenteil).

    Ich bin wie hier wohl die meisten ein Verfechter der Strategie: Funktionsaustritt wenn es sinn macht, und nicht unnötige Schachtelungen, die - wie ich finde - eher Code unübersichtlich als gut lesbar. Und wenn man zudem gewisse Regel macht das der Code einer Funktion maximal eine oder vielleicht noch 2 Bildschirmseiten füllen darf, ist die Komplexität meistens auch kein Thema.

    cu André



  • BlackPepper schrieb:

    double sum(double a, double b){
      return a + b;
    }
    
    [...]
    

    Hier würde ich doch einen Fehler erst in main sehen und nicht schon früher.

    Du musst deine Ergebnisse nicht erst in einer Variablen speichern um im Debugger sehen zu können was drin steht. Viele Debugger (vor allem in IDEs)bieten die Möglichkeit, den Wert von ganzen Ausdrücken zu berechnen. Du könntest also einen breakpoint in deine Funktion sum setzen und dir dort den Ausdruck "a+b" anzeigen lassen - nur bei Ausdrücken mit Nebeneffekten wäre ich da vorsichtig, weil die eine Änderung im Programm ergeben, die eigentlich garnicht im Code steht.


Anmelden zum Antworten