Übergeordnete Kontrollflusskonstrukte tendieren dazu, Konzepten in der Problemdomäne zu entsprechen. Ein if / else ist eine Entscheidung, die auf einer bestimmten Bedingung basiert. Eine Schleife fordert Sie auf, einige Aktionen wiederholt auszuführen. Sogar eine break-Anweisung besagt, "wir haben das wiederholt gemacht, aber jetzt müssen wir aufhören".
Eine goto-Anweisung entspricht dagegen eher einem Konzept im laufenden Programm, nicht in der Problemdomäne. Es heißt, die Ausführung an einer bestimmten Stelle im Programm fortzusetzen . Jemand, der den Code liest, muss ableiten, was dies in Bezug auf die Problemdomäne bedeutet.
Natürlich können alle übergeordneten Konstrukte in Form von gotos und einfachen bedingten Verzweigungen definiert werden. Das heißt nicht, dass sie nur verkleidet sind. Betrachten Sie sie als eingeschränkte GOTOS - und es sind die Einschränkungen, die sie nützlich machen. Eine break-Anweisung wird als Sprung an das Ende der einschließenden Schleife implementiert, aber es ist besser, sie als Operation für die gesamte Schleife zu betrachten.
Wenn alles andere gleich ist, ist Code, dessen Struktur die der Problemdomäne widerspiegelt, in der Regel leichter zu lesen und zu warten.
Es gibt keine Fälle, in denen eine goto-Anweisung unbedingt erforderlich ist (es gibt einen entsprechenden Satz ), aber es gibt Fälle, in denen dies die am wenigsten schlechte Lösung sein kann. Diese Fälle variieren von Sprache zu Sprache, je nachdem, welche übergeordneten Konstrukte die Sprache unterstützt.
In C glaube ich zum Beispiel, dass es drei grundlegende Szenarien gibt, in denen ein goto angemessen ist.
- Aus einer verschachtelten Schleife ausbrechen. Dies wäre unnötig, wenn die Sprache eine beschriftete break-Anweisung hätte.
- Rettung aus einem Codeabschnitt (normalerweise ein Funktionskörper) im Falle eines Fehlers oder eines anderen unerwarteten Ereignisses. Dies wäre unnötig, wenn die Sprache Ausnahmen hätte.
- Implementieren einer expliziten Zustandsmaschine. In diesem Fall (und ich denke nur in diesem Fall) entspricht ein goto direkt einem Konzept in der Problemdomäne, das von einem Zustand in einen angegebenen anderen Zustand übergeht, in dem der aktuelle Zustand dargestellt wird, durch den der Codeblock gerade ausgeführt wird .
Andererseits kann eine explizite Zustandsmaschine auch mit einer switch-Anweisung innerhalb einer Schleife implementiert werden. Dies hat den Vorteil, dass jeder Zustand an der gleichen Stelle im Code beginnt, was beispielsweise beim Debuggen hilfreich sein kann.
Die Hauptverwendung eines goto in einer einigermaßen modernen Sprache (eine, die if / else und Schleifen unterstützt) besteht darin, ein Kontrollflusskonstrukt zu simulieren, das in der Sprache fehlt.