Sichere Sprungbefehle



  • icarus2 schrieb:

    Wobei von gewissen Kreisen auch break, continue und vorzeitiges return als eine Art von goto bezeichnet wird.
    Habe darüber unter dem Titel "goto puts on a mask" gelesen. Wenn man frühzeitig aus Schleifen oder Funktionen springt kann dies zu Fehlern führen, da z.B. noch Code hätte ausgeführt werden sollen vor Beendigung der Funktion. Kann halt einfach Fehler geben.

    Das ist ein rhetorischer Trick. Man sollte über Für und Wider von break&co. nachdenken, ohne sich von goto benebeln zu lassen. Das Problem an goto ist ja nicht der Sprung an sich, sondern gerade das unkontrollierte.
    Außerdem funktioniert das Argument auch andersrum: Ein if ist auf Maschinenebene auch nur ein Sprung, also kann goto ja nicht so schlimm sein. Falsch, gar nicht erst so anfangen.



  • Danke an alle!!



  • Bashar schrieb:

    icarus2 schrieb:

    Wobei von gewissen Kreisen auch break, continue und vorzeitiges return als eine Art von goto bezeichnet wird.
    Habe darüber unter dem Titel "goto puts on a mask" gelesen. Wenn man frühzeitig aus Schleifen oder Funktionen springt kann dies zu Fehlern führen, da z.B. noch Code hätte ausgeführt werden sollen vor Beendigung der Funktion. Kann halt einfach Fehler geben.

    Das ist ein rhetorischer Trick. Man sollte über Für und Wider von break&co. nachdenken, ohne sich von goto benebeln zu lassen. Das Problem an goto ist ja nicht der Sprung an sich, sondern gerade das unkontrollierte.
    Außerdem funktioniert das Argument auch andersrum: Ein if ist auf Maschinenebene auch nur ein Sprung, also kann goto ja nicht so schlimm sein. Falsch, gar nicht erst so anfangen.

    Was auf Maschinenebene passiert interessiert den High-Level Programmierer ja sowieso kaum. Das Problem ist halt, dass man auch unkontrolliert (vorzeitig) aus einer Funktion oder Schleife herausspringen kann.
    Aber natürlich ist es nicht so schlimm wie bei normalem goto.
    Ich bin ja auch nicht gänzlich gegen break, continue und vorzeitige returns. Ich gehe seither nur etwas vorsichtiger damit um. Man muss sich halt schon überlegen ob man bereits aus der Funktion rausspringen darf oder nicht.



  • Da sag ich ja gar nichts gegen. Ich halte es nur für unredlich, damit zu argumentieren, dass das "maskierte gotos" seien.



  • Ich bin ja auch nicht gänzlich gegen break, continue und vorzeitige returns. Ich gehe seither nur etwas vorsichtiger damit um. Man muss sich halt schon überlegen ob man bereits aus der Funktion rausspringen darf oder nicht.

    Das gleiche kann man über goto sagen. Ich persönlich benutze häufig frühzeitiges return, z.B. im Fehlerfall. Da ist dann manchmal ein goto angebracht.

    if(foo())
        goto cleanup;
    /* ... */
    cleanup: free(allocated_memory);
    return some_value;
    

    Das gefährliche an goto ist ja nur das Unkontrollierte Springen, deshalb halte ich break, continue und return für absolut in Ordnung, weil man ja sofort sieht wohin gesprungen wird. Goto dagegen kann irgendwo in der Funktion rumspringen, setjmp sogar an jeden Punkt im kompletten Code.



  • wieso baut man generell eine bibliothek, wenn sie generell probleme vrursachen könnte?



  • Vermutlich weil die Erfinder von C der Meinung waren, daß die Programmierer intelligent genug sind zu wissen, was sie machen 😉

    @Topic: Während meiner aktiven C++-Zeit habe ich mir die Verwendung von RAII angewöhnt - da brauchst du keine expliziten Aufräumarbeiten und es ist (fast) egal auf welchem Weg du einen Code-Block verlässt. Aber andere Sprachen erfordern andere Vorgehensweisen, und inzwischen schraibe ich größere Funktionen auch mit einem einzigen Return (unmittelbar nach einer teilweise recht langen Serie von Done()-Aufrufen für alle kritischen Variablen).
    Mit break habe ich gar keine Probleme, gerade in umfangreichen und komplexen Schleifen, die andernfalls in einer endlos verschachtelten if-Kaskade und einer genauso langen Abbruchbedingung enden würden. (continue gehört zu den Features, die ich nur selten brauche)



  • Wenn goto statt anderer Ablaufkontrolle, dann sollte das übersichtlich bleiben und nur für besondere Zwecke eingesetzt werden, z.B. für den gezielten Ausstieg aus einer komplexen Iteration. Also ein solcher Sprung an das Funktionsende kann Sinn machen und sollte klar kommentiert sein. Wilde Sprünge hin und her sind extrem gefährlich, unübersichtlich und deshalb zu vermeiden (Spaghetticode). Du hast doch C und keinen alten BASIC-Interpreter!



  • transcend schrieb:

    wieso baut man generell eine bibliothek, wenn sie generell probleme vrursachen könnte?

    Ich komme zwar nicht aus dieser Zeit. Aber heute sind die Anwendungen um ein vielfaches grösser geworden. Deswegen brauchte man auch neue Vorgehensweisen. Bei kleinen, überschaubaren Programmen sind gotos nicht so schlimm, wie wenn man 50 Millionen Zeilen an Code hat.
    Ausserdem zeigt einem die Erfahrung auch falsches Designs auf. Ich bin mir sicher, dass ich 20 Jahren einiges, was man heute als good practice bezeichnet, anders gemacht wird.



  • icarus2 schrieb:

    Ich komme zwar nicht aus dieser Zeit. Aber heute sind die Anwendungen um ein vielfaches grösser geworden.

    👍
    C wurde ja ursprünglich entwickelt, um darin Unix zu implementieren (portabel). Ich bezweifle, dass im Kernel setjmp vorkam, aber in den vielen kleinen Utilities, warum nicht? cat, tail, tr, cp, da kann nicht viel schiefgehen. AFAIK benutzt ed setjmp zur Fehlerbehandlung.
    Heute sieht das anders aus, man kann keine monolithische 1-Millionen-Zeilen-Applikation in demselben Stil schreiben wie damals.



  • Ich bevorzuge gewisse Redundanzen gegenüber dem "unübersichtlichem" Herumhüpfen im Code.

    Allerdings - man korrigiere mich, wenn ich lügen sollte - darf ruhig jeder Entwickler für sich selbst entscheiden, ob er weiß, was sein Programm tun 'sollte' und deshalb Sprünge für legitim hält.

    In Bash Scripts habe ich auch ab und an exits in if Abfragen. Nicht unbedingt sauber, aber funktionell und verständlich. Sicherlich sind das zwei paar Schuhe, aber man muss eben abwägen, ob der Zweck die Mittel quasi heiligt ...



  • Schon die zweite Seite und niemanden stören die Sprünge im switch, das kein echter Block ist?
    http://en.wikipedia.org/wiki/Duff's_device



  • mngbd schrieb:

    Schon die zweite Seite und niemanden stören die Sprünge im switch, das kein echter Block ist?

    Wieso soll das jemanden stören? Auch ein switch ist ein sauberer Block! Zurück zur Frage nach nunmehr 2 Seiten: Srpünge (goto) sind in C möglich und legitim, man sollte sie aber nur in besonderen Fällen einsetzen, weil es in C bessere und übersichtlichtere Kontrollstrukturen für die blockweise Ablaufkontrolle eines Programmcode gibt.



  • Immer noch mein Favorit - COBOLs ALTER:

    Funktioniert etwa so:

    ANFANG:
    	MACH WAS
    	IF NOT IRGENDWAS
    		ALTER ANFANG TO ENDE
           * Jetzt springt das Programm nach ENDE
    	GO TO ANFANG
    ENDE:
    


  • Da darf natürlich INTERCALs COME FROM nicht fehlen.

    Ever since Dijkstra's seminal paper "Use of GOTO Considered Harmful" was published in Communications of the ACM, there has been a hue and cry against the use of GOTO. INTERCAL recognises the importance of structured programming and rebukes the GOTO, saying retro me iad[10]. In fact, the implementors of INTERCAL feel so strongly about the poor programming habits that GOTO encourages, that they implemented GOTO's opposite number, COME FROM. Thus if you had a program which looked similar to below:

    (1) PLEASE <YOUR STATEMENT HERE>
    .
    .
    .
    (2) DO COME FROM (1)
    

    anytime the program executed the statement at label 1, it would immediately jump to the statement at label 2 without executing any of the intervening statements. This is very difficult to follow and requires considerable expertise to use correctly and makes the code almost impossible to follow. That's right, baby -- information hiding.


Anmelden zum Antworten