Ist goto ausnahmslos immer schlecht?



  • sprunghaft schrieb:

    ... und trotzdem muesste nach s = 100 noch continue; stehen.

    naja, nicht wenn beide zeilen die letzten im schleifenkörper sind.
    🙂



  • +fricky schrieb:

    hartmut1164 schrieb:

    +fricky schrieb:

    hartmut1164 schrieb:

    NB: D. Knuth wurde damals ziemlich schnell von N. Wirth, von mindestens aehnlicher Reputation, widersprochen.

    trotzdem hat wirth in sein pascal ein goto-statement eingebaut, der alte witzbold.
    🙂

    Zumindest Modula-2 besitzt es nicht mehr (und glaube Modula-1 ebenfalls nicht).

    und wie kommt man in modula aus, sagen wir mal, einer dreifach verschachtelten schleife raus, wenn sich im innern entscheidet, dass keine durchläufe (auch nicht der äusseren schleifen) mehr nötig sind? oder kann man in modula sowas gar nicht erst programmieren?
    🙂

    Durch setzen von Variablen (kein Modula - nur mal kurz reingeschnuppert vor Ewigkeiten, aber C):

    bool Contains_5 (int    ***aDataCube,
                     int       iSize)
    {
    bool     fFound  = false;
    int      iLoop_x = 0,
             iLoop_y,
             iLoop_z;
    
    do
    {
        iLoop_y = 0;
        do {
            iLoop_z = 0;
            {
                if (aDataCube [iLoop_x] [iLoop_y] [iLoop_z] == 5)
                    fFound = true;
                else
                    iLoop_z++;
            } while ((iLoop_z < iSize) && (fFound == false));
    
        iLoop_y++;
        } while ((iLoop_y < iSize) && (fFound == false));
    
        iLoop_x++;
    } while ((iLoop_x < iSize) && (fFound == false));
    
    return fFound;
    }
    

    In der "freien Wildbahn" wuerde ich das noch etwas bauen, aber es duerfte klar sein, wie das prinzip aussieht.



  • _matze schrieb:

    +fricky schrieb:

    [...]sagen wir mal, einer dreifach verschachtelten schleife raus, wenn sich im innern entscheidet, dass keine durchläufe (auch nicht der äusseren schleifen) mehr nötig sind?

    Das ist genau der Fall, wo ich auch gerne mal ein goto einsetze. Zuletzt (wohl auch der einzige Einsatz in Code, der zum Kunden ging) bei einer Hough-Transformation, bei der Schleifen 7- oder 8-fach verschachtelt waren. Warum sollte man in jede Schleife eine zusätzliche Abbsuchbedingung packen...

    Der Algorithmus mag vielleicht mit achtfachen Schleifen arbeiten, aber man schneidet sich eher die rechte Hand ab als eine acht-fach geschachtelte Schleife wirklich so in Code zu schreiben. Im schlimmsten Falle muessen die Unterschleifen in eigene Funktionen gefasst werden.



  • hartmut1164 schrieb:

    Der Algorithmus mag vielleicht mit achtfachen Schleifen arbeiten, aber man schneidet sich eher die rechte Hand ab als eine acht-fach geschachtelte Schleife wirklich so in Code zu schreiben. Im schlimmsten Falle muessen die Unterschleifen in eigene Funktionen gefasst werden.

    und genau dann geht return eh viel besser als break!



  • +fricky schrieb:

    sprunghaft schrieb:

    Nicht für jede Schleife mit break; lässt sich eine äquivalente Schleife ohne break; erfinden.
    Zumindest kann ich mir nicht vorstellen, dass das Gegenteil beweisbar wäre.

    warum nicht? musst einfach nur in der schleife die abbruchbedingung gewaltsam herbeiführen, beispiel:

    for (s=0; s<100; s++)
      {
        if (s == 10)
          s = 100;   // selbe wirkung wie 'break'
      }
    

    🙂

    Das macht man eben nicht - ein for-Schleife wird dann verwendet, wenn man absolut sicher ist und unter allen Umstaenden, dass diese wirklich n-mal durchlaufen wird, ansonsten deklariert man eine Abbruchvariable, die die Schleife steuert.



  • hartmut1164 schrieb:

    Das macht man eben nicht - ein for-Schleife wird dann verwendet, wenn man absolut sicher ist und unter allen Umstaenden, dass diese wirklich n-mal durchlaufen wird, ansonsten deklariert man eine Abbruchvariable, die die Schleife steuert.

    falsch.

    for(Node* pos=anchor;pos!=0;pos=pos->next)
    

    aber ich gebe dir recht, daß man in c++ niemals an der laufvariablen rumfummelt. in basic hingegen tut man das dauernd machen. c ist ein bißchen dazwischen, fürchte ich.



  • hartmut1164 schrieb:

    In der "freien Wildbahn" wuerde ich das noch etwas bauen, aber es duerfte klar sein, wie das prinzip aussieht.

    ja, finde ich total fürchterlich, jedesmal dieses flag abzufragen. allein schon, dass es 'fFound' und nicht einfach 'Found' heisst, würde mich aufregen.

    hartmut1164 schrieb:

    Das macht man eben nicht - ein for-Schleife wird dann verwendet, wenn man absolut sicher ist und unter allen Umstaenden, dass diese wirklich n-mal durchlaufen wird, ansonsten deklariert man eine Abbruchvariable, die die Schleife steuert.

    dafür wirst du mich hassen, aber ich mache hin und wieder mal sowas:

    for (;;)  // nicht 'while(1)', das mögen manche compiler nicht.
    {
     ...
     if (...)
       break;
     ...
    }
    

    🙂



  • volkard schrieb:

    aber ich gebe dir recht, daß man in c++ niemals an der laufvariablen rumfummelt. in basic hingegen tut man das dauernd machen. c ist ein bißchen dazwischen, fürchte ich.

    in C eigentlich auch nicht. das beispiel mit der for-schleife sollte nur zeigen, wie man ohne break rauskommt. in wirklichkeit würde ich sowas nie machen.
    🙂



  • +fricky schrieb:

    dafür wirst du mich hassen, aber ich mache hin und wieder mal sowas:

    for (;;)  // nicht 'while(1)', das mögen manche compiler nicht.
    {
     ...
     if (...)
       break;
     ...
    }
    

    🙂

    hass wäre hier fehl am platz.

    open();
    for (;;)  // nicht 'while(1)', das mögen manche compiler nicht.
    {
     leseversuch();
     if (keineDatenMehrDa)
       break;
     verarbeitung();
    }
    close();
    

    wie soll man das sonst machen? künstliche variable, goto, codeduplikation, noch ne funktion?



  • volkard schrieb:

    wie soll man das sonst machen? künstliche variable, goto, codeduplikation, noch ne funktion?

    while (leseversuch() != keine_daten_mehr)
    {
       verarbeitung();
    }
    

    🙂



  • Oder, falls leseversuch() nichts passendes zurückgibt:

    open();
    while (leseversuch(), !keineDatenMehrDa) {
        verarbeitung();
    }
    close();
    

    Das wird natürlich wiederum die Feinde des Komma-Operators erzürnen.



  • volkard schrieb:

    wie soll man das sonst machen? künstliche variable, goto, codeduplikation, noch ne funktion?

    Das geht viel klarer:

    bool  fRunLoop;
    
    fRunLoop = Open ();
    while (fRunLoop == true)
    {
        if (LeseVersuch () == true)
            TueEbbes ();
        else
            fRunLoop = false;
    }
    

    Das Kind ist ist nach seiner Funktion benannt - fRunLoop ist ein Flag und steuert den Loop.



  • leseversuch() war natürlich nur ein platzhalter für ein paar zeilen code, die nicht sinnvoll in eine funktion ausgelagert werden können.



  • hartmut1164 schrieb:

    Das Kind ist ist nach seiner Funktion benannt - fRunLoop ist ein Flag und steuert den Loop.

    furchtbar.

    Damit hast du es geschafft das Programm schwerer wartbar zu machen da Flags die du lokal setzt, plötzlich globale Auswirkungen haben.

    *brrr*



  • hartmut1164 schrieb:

    volkard schrieb:

    wie soll man das sonst machen? künstliche variable, goto, codeduplikation, noch ne funktion?

    Das geht viel klarer:

    bool  fRunLoop;
    ...
    

    Das Kind ist ist nach seiner Funktion benannt - fRunLoop ist ein Flag und steuert den Loop.

    das kind ist die künstliche variable, die zu meiden war.
    das erinnert mich an

    #define RETURN(x) result=x; goto aufraum;
    


  • hartmut1164 schrieb:

    volkard schrieb:

    wie soll man das sonst machen? künstliche variable, goto, codeduplikation, noch ne funktion?

    Das geht viel klarer:

    bool  fRunLoop;
    
    fRunLoop = Open ();
    while (fRunLoop == true)
    {
        if (LeseVersuch () == true)
            TueEbbes ();
        else
            fRunLoop = false;
    }
    

    Das Kind ist ist nach seiner Funktion benannt - fRunLoop ist ein Flag und steuert den Loop.

    ich bin nochmal der Meinung, dass dieser Code schwer zu lesen ist und auf Dauer nervig zu warten. Ein gut eingesetzer Sprung kann die Lesbarkeit und Wartbarkeit deutlich erhöhen.



  • +fricky schrieb:

    hartmut1164 schrieb:

    In der "freien Wildbahn" wuerde ich das noch etwas bauen, aber es duerfte klar sein, wie das prinzip aussieht.

    ja, finde ich total fürchterlich, jedesmal dieses flag abzufragen. allein schon, dass es 'fFound' und nicht einfach 'Found' heisst, würde mich aufregen.

    In der freien Wildbahn haette irgentetwas in der Richtung gemacht und ganz auf Schleifen verzichtet und statt dessen mit einer einfachen Recursion gearbeitet:

    typedef struct ElementCube
    {
            int    iElement;
    
            ElementCube   *pNext_x = NULL,
                          *pNext_y = NULL,
                          *pNext_z = NULL;
    }
    
    ElementCube *CheckRow (ElementCube *pToCheck,
                           int          iToCheck)
    {
            if (pToCheck == NULL)
                    return NULL;
            else if (pToCheck->iElement == iToCheck)
                    return pToCheck;
            else
                    return (CheckRow (pToCheck->pNext_x));
    }
    
    ElementCube *CheckLevel (ElementCube *pToCheck,
                             int          iToCheck)
    {
            ElementCube *pReturn;
    
            pReturn = CheckRow (pToCheck, iToCheck);
    
            if (pReturn == NULL)
                    return CheckLevel (pToCheck->pNext_y, iToCheck)
            else
                    return pReturn;
    }
    
    ElementCube *CheckCube (ElementCube *pToCheck,
                            int          iToCheck)
    {
            ElementCube *pReturn;
    
            pReturn = CheckLevel (pToCheck, iToCheck);
            if (pReturn == NULL)
                    return CheckCube (pToCheck->pNext_z, iToCheck);
            else
                    return pReturn;
    }
    


  • hartmut1164 schrieb:

    In der freien Wildbahn haette irgentetwas in der Richtung gemacht und ganz auf Schleifen verzichtet und statt dessen mit einer einfachen Recursion gearbeitet:

    du hast zu lange am pascaltopf geschnüffelt. 🤡



  • volkard schrieb:

    hartmut1164 schrieb:

    In der freien Wildbahn haette irgentetwas in der Richtung gemacht und ganz auf Schleifen verzichtet und statt dessen mit einer einfachen Recursion gearbeitet:

    du hast zu lange am pascaltopf geschnüffelt. 🤡

    Pascal ist meine "Muttersprache" - und eine alte Liebe vergisst man nicht.



  • bei hartmut1164 sieht alles kompliziert und schwer wartbar aus, auch die komische ungarische notation macht es nicht gerade besser, eher im gegenteil.
    das kommt wohl am ende raus, wenn man sich zu sehr seine dogmatischen grundsätze klammert.


Anmelden zum Antworten