Ist goto noch evil...



  • hustbaer schrieb:

    Ja, das Beispiel ist ja auch totaler Mist.

    Dieser totale Mist stammt aus der Realität... ist schon länger her, ich habe die Funktion dann so gefixt:

    if (err)
    {
        cleanup(ptr);
        return err;
    }
    ...
    if (err)
    {
        cleanup(ptr);
        return err;
    }
    ...
    

    ptr ist ein Zeiger auf die Daten, die freigegeben werden müssen. Was soll man denn in diesem Fall noch machen 😕 Man bekommt diese Aufgabe, im fremden Code einen Fehler zu finden, was bedeutet, man muss die eine oder andere Funktion ändern. Dann stellt man fest, es gibt viel zu viele Pfade in der Funktion, die man kaputtmachen kann. Keine Zeit zum Durchblicken, nicht genug Papier, um sich eine Skizze zu machen und wenn man sich eine Skizze gemacht hat, dann sieht sie aus wie ein Spinngewebe, Durchblick = 0.
    Einfach goto rausschmeissen und das war's, sich das Leben einfach machen. Nachteil ist natürlich, man hat eine neue Datenstruktur, eine zusätzliche neue Funktion (cleanup()), viele returns.



  • CStoll schrieb:

    Wenn du zu viel aus einer Sprache rauswirfst, verlässt du den Bereich der Turing-Berechenbarkeit.

    Richtig ... das gibt einen Marienkäfer ins Aufgabenheft.

    Aber was hat das mit mir zu tun? Ich rede von Schleifen, die durch Intervall + Iterator ersetzbar sind. Auf Hochsprachenebene. Und nicht loop-Berechenbarkeit.

    Beschränkung auf Schleifen mit feststehenden Obergrenzen hat jmd anders in die Diskussion gebracht.



  • !rr!rr_. schrieb:

    Beschränkung auf Schleifen mit feststehenden Obergrenzen hat jmd anders in die Diskussion gebracht.

    Ja. Es war ein gewisser !rr!rr_., der zum Beispiel 1e1000 als Obergrenze nahm.



  • abc.w schrieb:

    Dieser totale Mist stammt aus der Realität... ist schon länger her, ich habe die Funktion dann so gefixt

    Ist das C-Code? Ansonsten wäre RAII wahrscheinlich die beste Idee gewesen.



  • volkard schrieb:

    Ja. Es war ein gewisser !rr!rr_., der zum Beispiel 1e1000 als Obergrenze nahm.

    das scheint ja arg kompliziert zu verstehen zu sein ...

    Pseudo-Code:

    while condition do .bla.bla. od
    

    kann in der Praxis ersetzt werden durch

    1 ... 1e1000 do
       if not condition then exit
       else .bla.bla.
    od
    

    Schleifen werden nun mal nicht öfter als 1e1000-mal ausgeführt.



  • abc.w schrieb:

    hustbaer schrieb:

    Ja, das Beispiel ist ja auch totaler Mist.

    Dieser totale Mist stammt aus der Realität... ist schon länger her, ich habe die Funktion dann so gefixt:

    if (err)
    {
        cleanup(ptr);
        return err;
    }
    ...
    if (err)
    {
        cleanup(ptr);
        return err;
    }
    ...
    

    ptr ist ein Zeiger auf die Daten, die freigegeben werden müssen. Was soll man denn in diesem Fall noch machen 😕 Man bekommt diese Aufgabe, im fremden Code einen Fehler zu finden, was bedeutet, man muss die eine oder andere Funktion ändern. Dann stellt man fest, es gibt viel zu viele Pfade in der Funktion, die man kaputtmachen kann. Keine Zeit zum Durchblicken, nicht genug Papier, um sich eine Skizze zu machen und wenn man sich eine Skizze gemacht hat, dann sieht sie aus wie ein Spinngewebe, Durchblick = 0.
    Einfach goto rausschmeissen und das war's, sich das Leben einfach machen. Nachteil ist natürlich, man hat eine neue Datenstruktur, eine zusätzliche neue Funktion (cleanup()), viele returns.

    Würde ich mit Deiner Funktion arbeiten müssen, würde ich sie zuerstmal zurückfixen.



  • Nexus schrieb:

    abc.w schrieb:

    Dieser totale Mist stammt aus der Realität... ist schon länger her, ich habe die Funktion dann so gefixt

    Ist das C-Code? Ansonsten wäre RAII wahrscheinlich die beste Idee gewesen.

    Das ist C-Code (C++ habe ich schon seit längerem nichts gemacht und muss jetzt wahrscheinlich alles neu lernen...) und das Beispiel stammte aus einem Linux-Kernel Treiber, weiss jetzt nicht, ob Quellcode davon öffentlich verfügbar ist. Der Linux-Kernel ist eigentlich voller gotos, wahrscheinlich, weil die Studenten es damals so angefangen haben (und sind es jetzt wahrscheinlich leid, geben es aber nicht zu) und man muss sagen, das Ganze funktioniert ja irgendwie.
    Muss man aber mit dem Code was machen, hat man plötzlich Angst, den Code "kaputt zu reparieren". Man sieht eine einfache Sprungmarke, die z.B. von zwei Stellen angesprungen wird, zwei Vorgeschichten sozusagen, bei zwei und mehr Sprungmarken spielt vielleicht (bestimmt...) die Reihenfolge eine Rolle, in welcher sie angesprungen werden, mal von da, mal von dort, man muss "Kombinatorik" betreiben, alle Pfade skizzieren auf Papier usw.

    volkard schrieb:

    Würde ich mit Deiner Funktion arbeiten müssen, würde ich sie zuerstmal zurückfixen.

    Bitte schön, ich habe keine Probleme damit. Wenn jemand da geübt ist, kann das Ganze überblicken, bitte schön, ich kann das nicht, deswegen mache ich es mir einfach bzw. bilde mir ein, dass es einfach ist, was ich da mache 🙂



  • !rr!rr_. schrieb:

    Pseudo-Code:

    while condition do .bla.bla. od
    

    kann in der Praxis ersetzt werden durch

    1 ... 1e1000 do
       if not condition then exit
       else .bla.bla.
    od
    

    Schleifen werden nun mal nicht öfter als 1e1000-mal ausgeführt.

    Da wäre ich mir nicht so sicher. Selbst im Umgang mit LOOP-Berechenbarkeit ist mir keine Obergrenze der Schleifendurchläufe bekannt.



  • das ist eben der Unterschied zwischen Theorie und Praxis.

    Das Gebiet heißt ja nicht umsonst "BerechenbarkeitsTheorie".



  • Man kann auch den Intervalltypen derart anpassen, dass als oberste Grenze unendlich zulässig ist. Dann hat man Turingvollständigkeit auch wieder theoretisch.
    Die Aussage "man kann Schleifen und goto durch Intervall und Iterator ersetzen" kann man aber trotzdem nicht so stehen lassen, denn das schließt noch nicht ein, dass man die Iteration auch abbrechen können muss. Und wenn wir schon eine Iteration haben, kann man das auch gleich mit Schleife übersetzen.



  • !rr!rr__ schrieb:

    das ist eben der Unterschied zwischen Theorie und Praxis.

    Auch in der Praxis ist es sinnlos, eine willkürliche Obergrenze festzulegen. Und es gibt genug Programme, da wird eben keine Grenze vorgesehen, weil es einfach Humbug wäre - die laufen solange, wie notwendig ist, um den Anwender glücklich zu machen.
    (von den Problemen, Zahlen in der Größenordnung um 1e1000 in der nötigen Genauigkeit zu verarbeiten, will ich gar nicht erst anfangen).



  • EOP schrieb:

    Am Ende wird alles immer zu einem goto.

    jne label, jmp label,...
    

    Seufz.

    Darum geht's aber überhaupt nicht.

    goto ist bei Hochsprachen böse, weil es zu Spaghetticode führt und die Struktur des Hochsprachencodes damit völlig zerrissen wird.



  • abc.w schrieb:

    berniebutt schrieb:

    ...
    hell:
    ...
    goto nirwana;
    ...
    nirwana:
    ... goto hell;
    ...
    

    Na, das ist ja trivial... es gibt z.B. so was:

    /* Hier macht jemand viele Sachen und bei Fehler springt er ans Ende der Funktion */
    if (err)
        goto label_a;
    ...
    if (err)
        goto label_b;
    ...
    if (err)
        goto label_c;
    ...
    if (err)
        goto label_d;
    ...
    if (err)
        goto label_e;
    ...
    /* keine Fehler, einfach return 0 */
        return 0;
    /* und das ist eine Art "Destruktor" am Ende der Funktion: */
    label_e:
        ...
    label_d:
        ...
    label_b:   /* Warum label_b vor label_c... */
        ...
    label_c:
        ...
    label_a:
        ...
        return err;
    

    warum kommt label_b vor label_c... 😕 🙂

    So ein Mist Code.

    Das ist viel sauberer:

    if (err)
    {
        mach a;
    }
    else
    {
      if (err)
      {
        mach b;
      }
      else
      {
        if (err)
        {
          mach c;
        }
        else
        {
          if (err)
          {
            mach d;
          }
          else
          {
            if (err)
            { 
               mach e;
            }
          }
        }
      }
    }
    

    Denn wenn man was reinprimmeln muß, dann zerhaut man sich nicht alles.



  • if (err)
    {
        mach a;
    }
    else
    {
      if (err)
      {
        mach b;
      }
      else
      {
        if (err)
        {
          mach c;
        }
        else
        {
          if (err)
          {
            mach d;
          }
          else
          {
            if (err)
            {
               mach e;
            }
          }
        }
      }
    }
    

    Der Code sieht aber rein optisch auch nicht besser aus... und was nicht gut aussieht, ist es meistens auch nicht 😃



  • !rr!rr__ schrieb:

    das ist eben der Unterschied zwischen Theorie und Praxis.

    Das Gebiet heißt ja nicht umsonst "BerechenbarkeitsTheorie".

    Ja, Einschätzungen über praktische Anforderungen haben ja glücklicherweise in der jüngsten Vergangenheit noch nie daneben gelegen. Warum sollte man also so etwas einfach realisierbares wie Turing-Vollständigkeit von einer Programmiersprache fordern, wenn es doch komplett unsinnig ist? 🙄



  • das hat was mit Beschreibungskomplexität zu tun:

    jede existierende Bandmaschine im Universum (Bandspeicher < oo !) läßt sich durch eine reguläre Sprache formalisieren. Diese Beschreibung wird aber i.a. lang und kompliziert sein.

    Mit einer Turing-vollständigen Sprache geht das oft viel kürzer und einfacher, und diese Effizienz in der Beschreibung überträgt sich auch auf allgemeine Probleme.



  • !rr!rr_. schrieb:

    Schleifen sind sehr wohl durch Intervall und Iterator ersetzbar. Alle in der Praxis auftretenden Schleifen werden höchstens 1e1000-mal durchlaufen, also reichen endliche Intervalle vollkommen aus.

    Bleibt noch die Endlosschleife - die tritt in der Praxis nicht auf, weil kein Programm unendlich lange läuft.

    In der Praxis treten aber auch Zahlenwerte in der Größenordnung 1e1000 nie in einer Form auf, mit der man praxisnahe über in Intervall iterieren kann.



  • So coded mann schrieb:

    ...
    So ein Mist Code.
    Das ist viel sauberer:

    ...
    

    Nein, es müsste dann so sein:

    if (err)
    {
        mach a;
    }
    else
    {
        if (err)
        {
            mach b;
            mach c;
            mach a;
        }
        else
        {
            if (err)
            {
                mach c;
                mach a;
            }
            else
            {
                if (err)
                {
                    mach d;
                    mach b;
                    mach c;
                    mach a;
                }
                else
                {
                    if (err)
                    { 
                        mach e;
                        mach d;
                        mach b;
                        mach c;
                        mach a;
                    }
                }
            }
        }
    }
    

    Ich finde so was auch nicht gut...



  • Leute, da hat jemand simpel danach gefragt, ob goto heute als evil gilt oder vielleicht doch noch seine Berechtigung finden kann! 🙂 7 Seiten Diskussion um was? 😕 Morgen fragt jemand, was er nehmen soll:

    i = i + 1;
    i++;
    ++i;
    

    Wieviele Seite gibt es dafür?



  • Gib doch einfach eine simple Antwort, dann sparst Du vielleicht 7 weitere Seiten 😉 .


Anmelden zum Antworten