C++ ist eigentlich eine schöne Sprache, nur...



  • Ein goto erzeugt wie schon gesagt immer Spaghetticode.
    Du springst aus deinem nachvollziehbaren Ablauf an eine andere komplett andere Stelle des Programms.
    Und je umfangreicher und verschachteleter der Schleifenrumpf oder Rümpfe umso schlimmer wird das.
    Ein goto ist nicht nur manchmal böse.



  • @Optimizer
    Dem kann ich nur zustimmen. 👍



  • Nur die Äußerung, das PHP eine Frickelsprache ist, stößt mir etwas auf.
    PHP hat mit Sicherheit einige Defiziete, ob es nun die Sicherheit oder aber die Umsetzung der OO geht.
    Aber zum Frickeln gehören immer zwei. Da kann in C++ genauso viel gefrickelt werden.
    Nur bei PHP wirst du durch die Möglichkeiten halt öfter zum frickeln inspiriert.



  • @Optimizer: sag ich ja auch gar nicht, ein derartiges Konstrukt hab ich persönlich nie gebraucht. Ich finde nur die Aussage Goto sei grundsätzlich böse ein wenig zu radikal. Es ist bewiesen, dass goto kein gutes Sprachmittel ist, aber man sollte sich immer die Nachteile vor Augen führen und selbst darüber nachdenken, ob diese hier wirklich greifen. Und irgendwas mit irgendwelchen Flags rumzuhantieren ist weniger gut nachzuvollziehen als ein brich die Schleife jetzt ab.
    Fhul, du sagst man würde in einen komplett anderen Programmteil geworfen, aber das ist nicht wirklich so, man bricht lediglich die Schleife ab.



  • Benutzername: schrieb:

    Und irgendwas mit irgendwelchen Flags rumzuhantieren ist weniger gut nachzuvollziehen als ein brich die Schleife jetzt ab.

    Dem stimme ich zu. Aber dann würde ich die Schleife mit einem return abbrechen. Ich sag jetzt schon nicht, dass jedes break böse ist, aber return ziehe ich klar vor. Auf jeden Fall behaupte ich, dass ein break 2 böse ist. Ich weiß, es gibt keine absolute Wahrheit bei sowas, aber man braucht sich das Leben schon nicht irre kompliziert machen, damit man ja nicht die eine Gelegenheit verpasst, wo ein break 2 die beste Lösung scheint. Da ist es leichter, break 2 und goto zu verteufeln, da verpasst man jetzt schon nichts. 🙂

    btw. Eine Schleife hat ja normal irgendeinen bestimmten Zweck, diesen Zweck kann man benennen und schon hat man eine Funktion. Man kann auch aus einer geschachtelten Schleife returnen. Es ist viel leserlicher.



  • Fhul, du sagst man würde in einen komplett anderen Programmteil geworfen, aber das ist nicht wirklich so, man bricht lediglich die Schleife ab

    Du springst an die Stelle, die du definierst. Ob das nun direkt nach den Schleifenrumpf ist kann sein, muss aber nicht.



  • ich hatte noch nie das Vergnügen PHP lesen zu müssen aber bei break n dreht sich mir echt der Magen um. Jedes goto mit benannter Sprungmarke ist ein Segen dagegen.



  • und dann noch endOfLoops2 und endOfLoops3 ...

    Einfach den Code besser in Funktionen verteilen und schon ist das ganz hinfällig.



  • [snip... wiedermal nicht bis zum Ende einen Thread gelesen... aber egal, trifft immer noch den Kontext]

    Benutzername: schrieb:

    Der Nachteil von Spaghetticode, ist dass er schwer nachzuvollziehen ist und das ist in diesem Fall nicht gegeben.

    Spätestens wenn etwas mehr Inhalt in der Scheife dazukommt ist es wieder gegeben. Und Programmierer sind (zumeist) faul [Nicht unbedingt weil sie es wirklich sind, sondern weil es etwas gibt das sich Zeitdruck nennt] und ändern dann nicht zwangsweise den Code wieder ab.

    Es gibt immer bessere Alternativen als goto. Ich komme seit 19 Jahren ohne goto aus (um genau zu sein, seit ich programmiere; Mag vielleicht auch daran liegen das ich die Programmierung unter gewisser Aufsicht erlernt habe, mein Vater ist auch in der Programmierung und QS Tätig ;p), da solle es auch anderen möglich sein es zu umgehen.

    cu André
    P.S: Und davon abgesehen sind tiefe Schleifenverschachtelungen auch meist nur ein Zeichen unschönen Codes. Meist läuft das mit langen Funktionen einher, und die sollte man eh lieber in ihre Einzelteile untergliedern. Alleine schon der Lesbarkeit wegen.



  • wer meint es gibt fett-gedruckt-immer bessere lösungen als gotos kann sich ja diesen artikel durchlesen

    http://stevemcconnell.com/ccgoto.htm



  • Optimizer schrieb:

    Wie wäre es mal mit einem anständigen Programmierstil? PHP ist eine Frickelsprache und kann als Vorbild nicht herhalten. Die ganze Diskussion break, break mit Zahl, goto usw. ist überflüssig, wenn man gescheite, vernünftige, kleine Funktionen schreibt.

    Mir ist schon oft aufgefallen, dass die ganzen Diskussionen über Kontrolstrukturen nur von Leuten geführt werden, die riesige Funktionen schreiben. Wer ordentlich programmiert, braucht solche "Features" nicht.

    Java hat weder break X noch goto. OMG wie kann man da nur Programme schreiben?

    asc hat mich dadrauf aufmerksam gemacht das ich auch noch nie goto eingesetzt habe und ich programmiere jetzt seit 13 Jahren.



  • Vevusio schrieb:

    wer meint es gibt fett-gedruckt-immer bessere lösungen als gotos kann sich ja diesen artikel durchlesen
    http://stevemcconnell.com/ccgoto.htm

    und natürlich den klassiker: http://pplab.snu.ac.kr/courses/adv_pl05/papers/p261-knuth.pdf
    🙂



  • fhul schrieb:

    Ein goto erzeugt wie schon gesagt immer Spaghetticode.
    Du springst aus deinem nachvollziehbaren Ablauf an eine andere komplett andere Stelle des Programms.
    Und je umfangreicher und verschachteleter der Schleifenrumpf oder Rümpfe umso schlimmer wird das.
    Ein goto ist nicht nur manchmal böse.

    Manchmal ist ein goto auch Sinnvoll. Zumindest in C.

    Sowas ist unschön:

    int fehler = 0;
    if (expr1) {
      ...
      if (expr 2) {
        ...
        if (expr3) {
          ...
          if (expr 4) {
             ...
          } else {
            fehler = 1;
          } 
        } else {
          fehler = 1
        }
      } else {
        fehler = 1;
      }
    } else {
      fehler = 1;
    }
    
    if (fehler) {
      [ aufräumen ]
      return FEHLER;
    } else {
      return ERFOLG;
    }
    

    schöner

    if (!expr1) {
      [ aufräumen ]
      return FEHLER;
    }
    
    if (!expr 2) {
      [ aufräumen ]
      return FEHLER;
    }
    
    if (!expr3) {
      [ aufräumen ]
      return FEHLER;
    }
    
    if (!expr 4) {
      [ aufräumen ]
      return FEHLER;
    }
    
    // aufräumen
    

    Weniger fehleranfällig und erheblich besser zu lesen:

    if (!expr1) {
      goto ERROR_CLEANUP;
    }
    
    if (!expr 2) {
      goto ERROR_CLEANUP;
    }
    
    if (!expr3) {
      goto ERROR_CLEANUP;
    }
    
    if (!expr 4) {
      goto ERROR_CLEANUP;
    }
    
    return ERFOLG;
    ERROR_CLEANUP:
      [ aufräumen ]
      return FEHLER;
    

    In C++ braucht man sowas nicht mehr und es wäre auch nicht Exception-Sicher. Aber in C trägt sowas zu Lesbarkeit bei.



  • Warum statt goto ERROR_ClEANUP nicht CleanUpOnError()? Hat mich ehrlich gesagt nicht überzeugt.



  • ProgChild schrieb:

    In C++ braucht man sowas nicht mehr und es wäre auch nicht Exception-Sicher.

    in C++ sind exceptions schon selber die gotos. naja, nicht ganz, eher sind exceptions sowas wie setjmp/longjmp in C.
    🙂



  • Optimizer schrieb:

    Warum statt goto ERROR_ClEANUP nicht CleanUpOnError()? Hat mich ehrlich gesagt nicht überzeugt.

    Du meinst für jede Funktion eine CleanUp Funktion? Und dann auch noch jedes aufzuräumende Element per Argument übergeben? Überzeugt mich nicht, dass das lesbarer sein wird.

    void foo_CleanUpOnError(FILE* fp, char* data, char* data2, int** data3, int len_data3) {
      [aufräumen]
    }
    
    int foo(void) {
    
    }
    
    void bar_CleanUpOnError(void) {
      [aufräumen]
    }
    
    int bar(void) {
    
    }
    


  • ProgChild schrieb:

    Optimizer schrieb:

    Warum statt goto ERROR_ClEANUP nicht CleanUpOnError()? Hat mich ehrlich gesagt nicht überzeugt.

    Du meinst für jede Funktion eine CleanUp Funktion? Und dann auch noch jedes aufzuräumende Element per Argument übergeben?

    Wieso denn jetzt beides? Aber klar, auf blöd ist es für jede Funktion, die was aufräumen muss, eine clean-up Funktion. Mit goto wäre es dann eine Liste von clean-up statements für jede Funktion. Ich sehe nicht, was daran besser ist.



  • Optimizer schrieb:

    Wieso denn jetzt beides? Aber klar, auf blöd ist es für jede Funktion, die was aufräumen muss, eine clean-up Funktion. Mit goto wäre es dann eine Liste von clean-up statements für jede Funktion. Ich sehe nicht, was daran besser ist.

    Vielleicht verstehe ich nicht, was du sagen willst.

    Sagen wir, du hast eine Funktion, die eine beliebig große Matrix mit malloc erstellt und mit Werten aus einer Datei füllt. Und einen Pointer auf **double, also die Matrix zurück liefert.

    Es kann ein Fehler auftreten, wenn die Datei nicht gefunden wirt und wenn sie ungültige Werte enthält.

    Um eine Cleanup Funktion benutzten zu können, müsste ich die Anzahl der Spalten, den double** Pointer und das FileHandle übergeben. Überall, wo ein Fehler beim einlesen auftritt. Diese Variablen habe ich aber schon in der Funktion zur verfügung.

    Was bringt mir der Mehraufwand für eine extra Funktion?



  • Ok. Und was ist jetzt der Mehraufwand? Ich sehe keinen. Ich markiere den Code, der die Matrix löscht, klick auf extract function und ruf sie überall dort auf, wo ich das brauche.

    Das hat sogar den Vorteil, dass ich die Funktion woanders wieder verwenden kann, ne Matrix löschen kann man ja immer brauchen.



  • Optimizer schrieb:

    Ok. Und was ist jetzt der Mehraufwand? Ich sehe keinen. Ich markiere den Code, der die Matrix löscht, klick auf extract function und ruf sie überall dort auf, wo ich das brauche.

    Der Mehraufwand ist, dass ich immer eine Recht lange Argumentliste übergeben muss, die überall stimmen muss. Wenn ist jetzt die Argumentliste ändere, weil ich z.B. zwei File-Handles schließen will, muss ich den Aufruf überall ändern.

    Optimizer schrieb:

    Das hat sogar den Vorteil, dass ich die Funktion woanders wieder verwenden kann, ne Matrix löschen kann man ja immer brauchen.

    Ich kann die Funktion woanders nicht gebrauchen, weil ich ja in der Funktion noch ein File-Handle schließe.


Anmelden zum Antworten