In diesem Thread sehen wir uns Beispiele für gute Verwendungen von an goto
in C oder C++. Es ist inspiriert von einer Antwort, die Leute gewählt haben, weil sie dachten, ich mache Witze.
Zusammenfassung (Etikett vom Original geändert, um die Absicht noch klarer zu machen):
infinite_loop:
// code goes here
goto infinite_loop;
Warum es besser ist als die Alternativen:
- Es ist spezifisch.
goto
ist das Sprachkonstrukt, das eine unbedingte Verzweigung bewirkt. Alternativen hängen von der Verwendung von Strukturen ab, die bedingte Verzweigungen mit einer degenerierten Always-True-Bedingung unterstützen. - Das Etikett dokumentiert die Absicht ohne zusätzliche Kommentare.
- Der Leser muss den dazwischenliegenden Code nicht vorzeitig scannen
break
s (obwohl es für einen prinzipienlosen Hacker immer noch möglich ist, zu simulieren
continue
mit frühgoto
).
Regeln:
- Tu so, als hätten die Gotophoben nicht gewonnen. Es versteht sich, dass das Obige nicht in echtem Code verwendet werden kann, da es gegen die etablierte Sprache verstößt.
- Gehen Sie davon aus, dass wir alle von „Goto gilt als schädlich“ gehört haben und wissen, dass goto zum Schreiben von Spaghetti-Code verwendet werden kann.
- Wenn Sie mit einem Beispiel nicht einverstanden sind, kritisieren Sie es allein aus technischen Gründen (‘Weil die Leute goto nicht mögen’ ist kein technischer Grund).
Mal sehen, ob wir wie Erwachsene darüber reden können.
Bearbeiten
Diese Frage scheint nun erledigt. Es generierte einige qualitativ hochwertige Antworten. Danke an alle, besonders an diejenigen, die mein kleines Loop-Beispiel ernst genommen haben. Die meisten Skeptiker waren besorgt über den fehlenden Blockbereich. Wie @quinmars in einem Kommentar betonte, können Sie immer Klammern um den Schleifenkörper legen. Das merke ich nebenbei an for(;;)
und while(true)
Geben Sie Ihnen die Klammern auch nicht kostenlos (und das Weglassen kann zu ärgerlichen Fehlern führen). Jedenfalls verschwende ich nicht noch mehr von deiner Denkkraft auf diese Kleinigkeit – ich kann mit dem Harmlosen und Idiomatischen leben for(;;)
und while(true)
(ebenso gut, wenn ich meinen Job behalten will).
Wenn ich die anderen Antworten betrachte, sehe ich, dass viele Leute das sehen goto
als etwas, das man immer anders umschreiben muss. Natürlich können Sie a vermeiden goto
durch Einführung einer Schleife, eines zusätzlichen Flags, eines Stapels von verschachtelten if
s, oder was auch immer, aber warum nicht überlegen, ob goto
ist vielleicht das beste Werkzeug für den Job? Anders ausgedrückt, wie viel Hässlichkeit sind die Menschen bereit, zu ertragen, um zu vermeiden, dass eine eingebaute Sprachfunktion für den beabsichtigten Zweck verwendet wird? Meiner Ansicht nach ist selbst das Hinzufügen einer Flagge ein zu hoher Preis. Ich mag es, wenn meine Variablen Dinge in den Problem- oder Lösungsdomänen darstellen. „Nur um a zu vermeiden goto
‘ schneidet es nicht ab.
Ich akzeptiere die erste Antwort, die das C-Muster für die Verzweigung zu einem Bereinigungsblock lieferte. IMO, das ist das stärkste Argument für a goto
aller geposteten Antworten, sicherlich wenn man es an den Verrenkungen misst, die ein Hasser durchmachen muss, um es zu vermeiden.
Ich verstehe nicht, warum die Gotophobes nicht einfach “#define goto report_to_your_supervisor_for_re_education_through_labour” oben in der Include-Datei des Projekts vorschreiben. Wenn es immer falsch ist, mach es unmöglich. Ansonsten ist es manchmal richtig…
– Steve Jessop
30. Oktober 2008 um 1:36 Uhr
“kann nicht in echtem Code verwendet werden”? Ich verwende es immer dann in “echtem” Code, wenn es das beste Werkzeug für den Job ist. „Etablierte Redewendung“ ist ein schöner Euphemismus für „blinde Dogmatik“.
– Dan Formen
18. August 2010 um 15:58 Uhr
Ich stimme zu, dass “goto” nützlich sein kann (es gibt unten großartige Beispiele), aber ich stimme Ihrem spezifischen Beispiel nicht zu. Eine Zeile mit der Aufschrift „goto infinite_loop“ klingt so, als würde sie bedeuten „Gehe zu dem Teil des Codes, an dem wir mit der Endlosschleife beginnen werden“, wie in „initialize(); set_things_up(); goto infinite_loop;“ wenn Sie wirklich vermitteln wollen, dass „die nächste Iteration der Schleife beginnen, in der wir uns bereits befinden“, was völlig anders ist. Wenn Sie versuchen, eine Schleife zu erstellen, und Ihre Sprache über Konstrukte verfügt, die speziell für Schleifen entwickelt wurden, verwenden Sie diese zur Verdeutlichung. while(true) {foo()} ist ziemlich eindeutig.
– Josch
21. Dezember 2010 um 19:00 Uhr
Ein großer Nachteil Ihres Beispiels ist, dass nicht ersichtlich ist, welche andere Stellen im Code können entscheiden, zu diesem Label zu springen. Eine “normale” Endlosschleife (
for (;;)
) hat keine überraschenden Einstiegspunkte.– jalf
5. Januar 2011 um 19:56 Uhr
@György: ja, aber das ist kein Einstiegspunkt.
– jalf
5. März 2011 um 10:36 Uhr