GOTO gilt immer noch als schädlich?
Jeder ist sich bewusst von Dijkstra Briefe an die Redaktion: go to statement considered harmful (auch hier .html-Transkript und hier .pdf) und es hat einen gewaltigen push seit dieser Zeit meiden die goto-Anweisung, Wann immer möglich. Obwohl es möglich ist, verwenden Sie goto, um zu produzieren wartbaren, weitläufige code, es bleibt dennoch in moderne Programmiersprachen. Auch der fortgeschrittene Fortsetzung control-Struktur in Schema beschrieben werden kann, wie ein anspruchsvolles springen.
Welche Umstände rechtfertigen die Verwendung von goto? Wann ist es am besten zu vermeiden?
Als follow-up-Frage: C # bietet ein paar Funktionen setjmp und longjmp, die Fähigkeit zu springen, die nicht nur innerhalb des aktuellen stack-frame, aber innerhalb des aufrufenden frames. Sollten diese berücksichtigt werden, so gefährlich, wie goto? Noch gefährlicher?
Dijkstra selbst bedauerte, dass Titel, für die er nicht zuständig war. Am Ende EWD1308 (auch hier .pdf), schrieb er:
Schließlich eine kurze Geschichte für den Datensatz.
Im Jahr 1968, der Communications of the ACM
veröffentlicht einen text von mir unter die
Titel "Die goto-Anweisung als
schädlich", welche in späteren Jahren würde
werden am häufigsten verwiesen wird,
leider, jedoch, oft von Autoren
wer hatte nicht mehr gesehen, als seine
Titel, die zu einem Grundpfeiler
mein Ruhm, indem er eine Vorlage: wir
würde sehen, alle Arten von Artikeln unter
der Titel "X als schädlich" für
fast alle X, darunter eine mit dem Titel
"Dijkstra als schädlich". Aber
was war passiert? Ich hatte eingereicht
Papier unter dem Titel "Fall gegen
die goto-Anweisung", die im Auftrag
um die Geschwindigkeit der Veröffentlichung, die
editor geändert hatte, in einem "Brief an
der Editor", und in dem Prozess, den er hatte
einen neuen Titel mit seiner eigenen
Erfindung! Der editor wurde Niklaus
Wirth.
Einer gut durchdachten klassischen Papier über dieses Thema, aufeinander abgestimmt sein, dass der Dijkstra -, ist Structured Programming with go to Statementsvon Donald E. Knuth. Lesen hilft, wieder Kontext und eine nicht-dogmatische Verständnis des Themas. In diesem Papier, Dijkstra ' s Meinung zu diesem Fall berichtet, und ist sogar noch stark:
Donald E. Knuth: ich glaube, dass durch die Präsentation eines solchen
Ansicht bin ich im Grunde gar nicht uneins
scharf mit Dijkstra ' s Ideen, da
er schrieb vor kurzem die folgenden:
"Please don' T fallen in die Falle
zu glauben, dass ich bin furchtbar
dogmatical über [gehe zu
Anweisung]. Habe ich das unangenehm
das Gefühl, andere machen ein
religion, aus der es, als wenn die
konzeptionelle Probleme der Programmierung
konnte gelöst werden durch einen einzigen trick, mit
eine einfache form der Codierung Disziplin!"
InformationsquelleAutor der Frage |
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die folgenden Aussagen sind Verallgemeinerungen; es ist zwar immer möglich, darum zu bitten, Ausnahme, es in der Regel (nach meiner Erfahrung und bescheidenen Meinung nach) nicht Wert, die Risiken.
Fußnoten zu den oben genannten:
Bezüglich Punkt 2, betrachten Sie den folgenden code:
Auf dem "etwas tun" Punkt im code, können wir heute mit großer zuversicht, dass
a
größer ist alsb
. (Ja, ich Ignoriere die Möglichkeit, nicht abgefangene integer-überlauf. Lassen Sie sich nicht bog, ein einfaches Beispiel.)Auf der anderen Seite, wenn der code gelesen hatte, auf diese Weise:
Die Vielzahl von Möglichkeiten, um zu label 10 bedeutet, dass wir haben, um härter zu arbeiten, um zuversichtlich in die Beziehungen zwischen
a
undb
an diesem Punkt. (In der Tat, im Allgemeinen Fall ist es undecideable!)Bezüglich Punkt 4, die ganze Vorstellung vom "irgendwo" im code, ist nur eine Metapher. Nichts ist wirklich "gehen" irgendwo im inneren der CPU, außer Elektronen und Photonen (für die Abwärme). Manchmal geben wir eine Metapher für eine andere, nützlichere, ein. Ich erinnere mich an die Begegnung mit (ein paar Jahrzehnte her!) eine Sprache, wo
wurde umgesetzt auf eine virtuelle Maschine durch das kompilieren von Aktion 1 und Aktion 2 als out-of-line-parameterlosen-Routinen, wird bei Verwendung einer einzelnen zwei-argument-VM-opcode, die die boolschen Wert der Bedingung zu berufen, den ein oder anderen. Das Konzept war einfach: "wählen Sie, was Sie aufrufen, jetzt" statt "gehen Sie hier-oder dorthin gehen". Wieder, nur eine Veränderung der Metapher.
InformationsquelleAutor der Antwort
Ein Kollege von mir sagte, der einzige Grund für die Verwendung eines GOTO ist, wenn Sie programmiert sich selbst, so weit in eine Ecke, es ist der einzige Ausweg. In anderen Worten, die richtige Gestaltung vor der Zeit und werden Sie nicht brauchen, um eine GOTO-später.
Ich gedacht, dass dieser comic verdeutlicht, dass es sich schön "könnte ich das Programm neu zu strukturieren flow, oder verwenden Sie ein wenig 'GEHE' statt." Ein GOTO ist ein schwacher Ausweg, wenn Sie haben ein schwaches design. Velociraptoren Jagd auf die schwachen.
InformationsquelleAutor der Antwort
Manchmal ist es zulässig, verwenden Sie GOTO, als eine alternative zur Ausnahmebehandlung innerhalb einer einzigen Funktion:
COM-code scheint in dieses Muster fallen ziemlich oft.
InformationsquelleAutor der Antwort
Kann ich nur daran erinnern, mit einem goto einmal. Ich hatte eine Serie von fünf verschachtelten loops gezählt und ich brauchte, um in der Lage zu brechen die gesamte Struktur von innen frühzeitig, basierend auf bestimmten Bedingungen:
Konnte ich einfach haben, einfach erklärt, ein boolean break-variable und verwendet es als Teil der bedingte for-each-Schleife, aber in diesem Fall habe ich beschlossen eine GOTO-war ebenso praktisch und ebenso lesbar.
Keine Velociraptoren angegriffen mich.
InformationsquelleAutor der Antwort
Das hatten wir schon Diskussion und ich stehe mein Punkt.
Außerdem habe ich die Nase voll mit Menschen beschreiben übergeordnete Strukturen der Sprache als "
goto
im Unglück", weil Sie offenbar nicht den Punkt an alle. Zum Beispiel:Dass das kompletter Unsinn. Jeder control-Struktur umgesetzt werden können, in Bezug auf
goto
aber diese Beobachtung ist völlig trivial und nutzlos.goto
gilt nicht als schädlich, weil seine positiven Effekte, die aber wegen Ihrer negativen Auswirkungen, und diese wurden beseitigt, indem die strukturierte Programmierung.Ähnlich, nämlich "SPRINGEN ist ein tool und wie alle Werkzeuge kann es benutzt und missbraucht," ist vollkommen daneben. Kein moderner Bau-Arbeiter mit einem rock und zu behaupten, es "ist ein Werkzeug." Steine wurden ersetzt durch die Hämmer.
goto
wurde ersetzt durch Kontroll-Strukturen. Wenn die Bauarbeiter waren gestrandet in der wildnis, ohne einem hammer, natürlich, er würde einen rock statt. Wenn ein Programmierer Verwendung einer minderwertigen Programmiersprache, die nicht feature X, gut, natürlich, Sie können, um verwendengoto
statt. Aber wenn Sie es verwendet überall sonst statt der entsprechenden Sprache verfügen Sie noch nicht eindeutig verstanden, die Sprache richtig und verwendet es falsch. Es ist wirklich so einfach.InformationsquelleAutor der Antwort
Springen ist extrem niedrig auf meiner Liste der Dinge, die in ein Programm nur aus Gründen der es. Das bedeutet nicht, dass es inakzeptabel ist.
Springen kann nett sein, für die state-machines. Eine switch-Anweisung in einer Schleife (in der Reihenfolge der typischen Bedeutung): (a) nicht wirklich repräsentativ für die Ablaufsteuerung, (b) hässlich, (c) potentiell ineffizient-je nach Sprache und compiler. So dass Sie am Ende schreiben Sie eine Funktion pro Staat, und Dinge zu tun, wie "return NEXT_STATE;", die sogar aus wie springen.
Zugegeben, es ist schwierig, code Zustandsautomaten in einer Weise, die machen Sie leicht zu verstehen. Jedoch keine, die Schwierigkeit ist zu tun mit der Verwendung von goto, und keiner kann es reduziert werden, indem man alternative Strukturen kontrollieren. Es sei denn, Ihre Sprache hat eine 'state-machine' zu konstruieren. Mir tut es nicht.
Bei den seltenen Gelegenheiten, wenn Ihr Algorithmus richtig ist, die meisten nachvollziehbar, in Bezug auf einen Pfad durch eine Sequenz von Knoten (Zustände), verbunden mit einem begrenzten Satz von zulässigen übergänge (gotos), eher als durch eine mehr spezifische Ablaufsteuerung (Schleifen, Bedingungen, Dingsbums), dann sollte das explizit im code. Und sollten Sie zeichnen ein hübsches Diagramm.
setjmp/longjmp kann nett sein für die Implementierung von Ausnahmen und Ausnahme-Verhalten. Zwar nicht überall gelobt, Ausnahmen sind in der Regel als eine "gültige" control-Struktur.
setjmp/longjmp sind 'gefährlicher' als springen in dem Sinne, dass Sie sind schwieriger zu verwenden korrekt ist, geschweige denn nachvollziehbar.
Unter springen aus einer C würde machen es nicht gerade leichter, guten code zu schreiben in C. In der Tat, es würde eher den Punkt verpassen, dass C soll werden kann als ein besserer assembler.
Weiter, es wird "Zeiger als schädlich", dann "duck typing als schädlich". Wer wird übrig sein, um dich zu verteidigen, wenn Sie kommen, nehmen Sie Ihre unsichere Programmierung Konstrukt? Eh?
InformationsquelleAutor der Antwort
In Linux: Verwenden von goto Im Kernel-Code auf Kernel-Trap, da ist eine Diskussion mit Linus Torvalds und einen "neuen Mann" über die Verwendung von GOTOs in Linux-code. Es gibt einige sehr gute Punkte gibt, und Linus, gekleidet in das übliche Arroganz 🙂
Einige Passagen:
-
-
InformationsquelleAutor der Antwort
In C,
goto
funktioniert nur im Rahmen der aktuellen Funktion, die dazu neigt, zu lokalisieren potenzielle bugs.setjmp
undlongjmp
sind weit gefährlicher, nicht-lokal, kompliziert und von der Implementierung abhängig. In der Praxis sind Sie aber zu unbekannt und ungewöhnlich, dass viele Probleme verursachen.Ich glaube, dass die Gefahr von
goto
in C ist stark übertrieben. Denken Sie daran, dass die ursprünglichegoto
Argumente fand zurück in die Tage der Sprachen wie altmodisch BASIC, wo Anfänger schreiben würde spaghetti-code wie folgt:Hier Linus beschreibt eine entsprechende Verwendung von
goto
: http://www.kernel.org/doc/Documentation/CodingStyle (Kapitel 7).InformationsquelleAutor der Antwort
Heute, es ist schwer zu sehen, die große Sache über die
GOTO
Aussage, weil die "strukturierte Programmierung" Menschen meist gewann die Debatte und die heutigen Sprachen haben ausreichend Kontrollfluss-Strukturen zu vermeidenGOTO
.Zählen Sie die Anzahl der
goto
s in einem modernen C-Programm. Fügen Sie nun die Anzahl derbreak
continue
undreturn
Aussagen. Darüber hinaus fügen Sie die Anzahl der Zeiten, die Sie verwendenif
else
while
switch
odercase
. Das ist ungefähr, wie vieleGOTO
s Ihrem Programm gehabt hätte, wenn Sie schreiben in FORTRAN oder BASIC im Jahre 1968, als der Dijkstra schrieb seinen Brief.Programmiersprachen zu der Zeit fehlten in der Ablaufsteuerung. Zum Beispiel, in der original-Dartmouth-BASIC:
IF
Aussagen hatte keineELSE
. Wenn Sie wollte, Sie hatte zu schreiben:Selbst wenn Ihr
IF
Anweisung nicht brauchen eineELSE
war, war es dennoch nur eine einzige Linie, die in der Regel aus einemGOTO
.Gab es keine
DO...LOOP
- Anweisung. Für nicht-FOR
Schleifen, Sie hatte bis zum Ende der Schleife mit einer explizitenGOTO
oderIF...GOTO
zurück an den Anfang.Gab es keine
SELECT CASE
. Sie hattenON...GOTO
.So, Sie endete mit einem viel von
GOTO
s in Ihrem Programm. Und Sie konnte nicht davon abhängen, die Beschränkung derGOTO
s in einem einzigen Unterprogramm (weilGOSUB...RETURN
war so ein schwaches Konzept von Unterprogrammen), so dass dieseGOTO
s gehen könnte überall. Offensichtlich, dies machte die Ablaufsteuerung schwer zu Folgen.Dies ist, wo die anti-
GOTO
Bewegung kam.InformationsquelleAutor der Antwort
Gehen Zu können eine Art stand-in für das "wirkliche" exception handling in bestimmten Fällen. Bedenken Sie:
Offensichtlich ist dieser code wurde vereinfacht, weniger Platz, so don T erhalten auch aufgelegt auf die details. Aber erwägen Sie eine alternative, die ich gesehen habe die alle zu oft in Produktion code durch den Programmierer gehen, um absurde Längen, vermeiden Sie die Verwendung von goto:
Nun funktional dieser code macht genau dasselbe. In der Tat, der code, der vom compiler erzeugt wird ist nahezu identisch. Jedoch, in der programmer ' s Eifer zu beschwichtigen Nogoto (die gefürchtete Gott des akademischen Tadel), dieser Programmierer hat völlig gebrochen die zugrunde liegenden idiom, das die
while
Schleife darstellt, und haben eine reelle Zahl auf die Lesbarkeit des Codes. Das ist nicht besser.So, die moral von der Geschichte ist, wenn Sie sich dem Rückgriff auf etwas wirklich dummes gemacht um zu vermeiden, mit goto, dann nicht.
InformationsquelleAutor der Antwort
Donald E. Knuth beantwortet diese Frage in dem Buch "Literate Programming", 1992 CSLI. Auf p ist. 17 es ist ein essay "Strukturierte Programmierung mit goto-Anweisungen" (PDF). Ich denke, der Artikel könnte veröffentlicht wurden, in anderen Büchern auch.
Der Artikel beschreibt Dijkstra ' s Vorschlag und beschreibt die Umstände, unter denen dies gilt. Aber er bietet auch eine Reihe Gegenbeispiele (Probleme und algorithmen), die nicht einfach reproduziert werden mithilfe von strukturierten Schleifen nur.
Der Artikel enthält eine vollständige Beschreibung des Problems, die Historie, Beispiele und Gegenbeispiele.
InformationsquelleAutor der Antwort
Angezogen von Jay Ballou hinzufügen einer Antwort, werde ich hinzufügen, meine £0.02. Wenn Bruno Ranschaert hatte nicht getan, hätte ich erwähnt, Knuth ' s "Structured Programming with GOTO Statements" Artikel.
So eine Sache, ich habe nicht gesehen, diskutiert wird, sind die Art von code, die, obwohl Sie nicht gerade üblich, gelehrt wurde in Fortran-text-Bücher. Dinge wie die erweiterte Palette von einer DO-loop-und open-kodierten Unterprogrammen (denken Sie daran, dies wäre Fortran II, oder Fortran-IV, - oder Fortran-66 - nicht Fortran 77 oder 90). Es gibt zumindest die chance, dass die syntaktische details sind ungenau, aber die Konzepte sollten genau genug. Die snippets sind jeweils innerhalb einer einzigen Funktion.
Beachten Sie, dass die ausgezeichneten aber veraltet (und vergriffene) Buch ' Die Elemente der Programming-Stil, 2. Auflage " von Kernighan & Plauger, enthält einige real-life-Beispiele von Missbrauch von SPRINGEN von der Programmierung text-Bücher seiner Zeit (späte 70er Jahre). Das material unten nicht aus diesem Buch, aber.
Erweiterte Reichweite für eine DO-Schleife
Einen Grund für solchen Unsinn war das gute alte-fashioned-punch-Karte. Sie können feststellen, dass die Etiketten (schön aus der Reihenfolge, denn das war kanonischen Stil!) sind in Spalte 1 (eigentlich musste Sie in den Spalten 1-5) und der code in den Spalten 7-72 (Spalte 6 war die Fortsetzung marker-Spalte). Spalten 73-80 gegeben wäre, eine laufende Nummer, und es gab Maschinen, die würde Sortieren punch Karte-decks, die in Sequenz-Nummer um. Wenn Sie Ihr Programm auf den sequenzierten Karten und brauchte noch ein paar Karten (Zeilen) in der Mitte von einer Schleife, man müsste repunch alles, was nach diesen Zeilen extra. Allerdings, wenn Sie ersetzt eine Karte mit der GOTO-Sachen, die Sie vermeiden könnte, resequencing alle Karten - Sie versteckt die neuen Karten, die am Ende der routine mit neuen Sequenznummern. Denken, es sei der erste Versuch der "green-computing" - das speichern von Lochkarten (oder, genauer gesagt, sparen Sie Arbeits - und eine Einsparung von Folgeschäden-Eingabe-Fehler).
Oh, Sie könnten auch beachten Sie, dass ich Betrug und nicht Schreien - Fortran IV geschrieben wurde, in allen upper-case-normalerweise.
Open-codiert Unterprogramm
Dem SPRINGEN zwischen den Etiketten 76 und 54 ist eine version von computed goto. Wenn die variable i hat den Wert 1, goto die erste Bezeichnung in der Liste (123); wenn Sie den Wert 2, gehe zu der zweiten, und so weiter. Das fragment von 76 auf die berechnete goto ist die open-Unterprogramm codiert. Es war ein Stück code, das ausgeführt eher wie ein Unterprogramm, aber geschrieben in dem Körper eine Funktion. (Fortran hatte auch Anweisung Funktionen - die embedded-Funktionen, die auf einer einzelnen Zeile.)
Es gibt schlechtere Konstrukte als die berechnete goto - Sie können Etiketten zuweisen, Variablen und verwenden Sie dann eine zugewiesen springen. Googeln zugeordnet springen sagt mir, es wurde gelöscht, von Fortran 95. Kreide für die strukturierte Programmierung revolution, die könnte ziemlich gesagt werden, dass Sie begonnen haben, in der öffentlichkeit mit Dijkstra "GOTO considered harmful" Brief oder einen Artikel.
Ohne eine gewisse Kenntnis der Arten von Dingen, die getan wurden in Fortran (und in anderen Sprachen, von denen die meisten Recht gefallen von der Strecke), es ist schwer für uns Neulinge zu verstehen, das Ausmaß des Problems, die Dijkstra zu tun hatte. Zum Kuckuck, ich habe nicht mit der Programmierung beginnen, bis zehn Jahre nach diesem Brief wurde veröffentlicht (aber ich hatte das Pech, dass das Programm in Fortran IV für eine Weile).
InformationsquelleAutor der Antwort
Springen als hilfreich.
Begann ich die Programmierung in 1975. Zu 1970er-Jahre-ära-Programmierer, die Worte "goto considered harmful" mehr oder weniger gesagt, dass neue Programmiersprachen mit modernen Kontrollstrukturen waren einen Versuch Wert. Wir haben versucht, die neuen Sprachen. Wir schnell umgewandelt. Wir gingen nie zurück.
Wir haben nie ging zurück, aber, wenn Sie jünger sind, dann haben Sie noch nie da gewesen in den ersten Platz.
Nun ein hintergrund in alten Programmiersprachen möglicherweise nicht sehr nützlich, außer als Indikator für die programmer ' s Alter. Ungeachtet, jüngere Programmierer fehlt dieser hintergrund, so dass Sie nicht mehr verstehen, die Botschaft, die der slogan "goto considered harmful" vermittelt Ihrer Zielgruppe zu der Zeit als es eingeführt wurde.
Slogans, die man nicht versteht, sind nicht sehr aufschlussreich. Es ist wahrscheinlich am besten vergessen Sie solche Sprüche. Solche Sprüche nicht helfen.
Diesem besonderen Motto jedoch "Goto considered harmful", hat in eine untote Leben seiner eigenen.
Kann springen nicht missbraucht werden? Antwort: sicher, aber so was? Praktisch jeder Programmierung element kann missbraucht werden. Die bescheidenen
bool
zum Beispiel missbraucht wird, oft mehr, als manche von uns glauben mag.Ich hingegen kann mich nicht erinnern, treffen eine einzige, tatsächliche Instanz der goto-Missbrauch seit 1990.
Das größte problem mit dem springen ist wohl nicht technischer, sondern ein sozialer. Programmierer, die nicht wissen, sehr viel scheint manchmal das Gefühl, dass der veralteten springen macht Sie klingen smart. Sie müssen möglicherweise erfüllen diese Programmierer von Zeit zu Zeit. So ist das Leben.
Das Schlimmste, was über das springen von heute ist, dass es nicht genug benutzt.
InformationsquelleAutor der Antwort
Gibt es keine solche Dinge wie GOTO considered harmful.
GOTO ist ein tool und wie alle Werkzeuge, die verwendet werden können und missbraucht.
Gibt es jedoch viele tools, die in der Welt des Programmierens, haben eine Tendenz zu sein missbraucht mehr als verwendetund GOTO ist einer von Ihnen. die MIT Aussage von Delphi ist eine andere.
Persönlich ich nicht verwenden, entweder in typischer codeaber ich hatte die ungerade Nutzung sowohl SPRINGEN und MITdie zugesichert werden, und eine alternative Lösung wäre, haben die mehr code.
Die beste Lösung wäre, dass der compiler nur warnen Sie, dass das Schlüsselwort war beflecktenund man müsste ein paar Sachen von pragma-Direktiven um die Aussage, um loszuwerden, die Warnungen.
Es ist wie zu sagen, Ihre Kinder zu nicht ausgeführt mit einer Schere. Scheren sind nicht schlecht, aber einige Verwendung von Ihnen sind Sie vielleicht nicht die beste Art, Ihre Gesundheit zu halten.
InformationsquelleAutor der Antwort
Seit ich damit anfing, ein paar Dinge in den linux-kernel, gotos don ' T stört mich so viel, wie Sie es einst Taten. Auf den ersten ich war ein bisschen entsetzt zu sehen, dass Sie (die kernel-Jungs) Hinzugefügt gotos in meinem code. Ich habe seit daran gewöhnt, die Verwendung von gotos, in einigen wenigen Kontexten, und wird nun gelegentlich selbst nutzen. In der Regel, es ist ein springen, springt an das Ende einer Funktion zu tun, irgendeine Art von "cleanup" und " bail out, anstelle der Duplizierung, die gleiche Aufräum-und Rettungsplan in mehreren Orten in der Funktion. Und in der Regel, es ist nicht etwas, das groß genug ist, um die hand aus, um eine andere Funktion-z.B. die Befreiung einige lokal (k)malloc ' ed Variablen ist ein typischer Fall.
Habe ich geschrieben code, der benutzt setjmp/longjmp nur einmal. Es war in einem MIDI-drum-Sequenzer-Programm. Die Wiedergabe geschah in einem separaten Prozess aus alle user-Interaktionen und der Wiedergabe verwendet shared memory mit dem UI-Prozess, um die begrenzte info es erforderlich ist, um die Wiedergabe. Wenn der Benutzer wollte, um die Wiedergabe anzuhalten, die Wiedergabe-Prozess hat gerade eine longjmp "zurück zum Anfang" zu beginnen, anstatt eine komplizierte Rückabwicklung, wo immer es passiert zu sein, ausgeführt werden, wenn der user wollte, es zu stoppen. Es hat Super geklappt, war einfach und ich hatte nie irgendwelche Probleme oder Fehler im Zusammenhang mit in dieser Instanz.
setjmp/longjmp haben Ihren Platz-aber das ist, wirst du wahrscheinlich nicht besuchen, aber einmal in eine sehr lange Zeit.
Edit: ich sah nur auf den code. Es war eigentlich siglongjmp (), die ich verwendet habe, nicht longjmp (nicht, dass es eine große Sache, aber ich hatte vergessen, dass siglongjmp noch gar nicht gab.)
InformationsquelleAutor der Antwort
War es noch nie, solange Sie in der Lage waren, für sich selbst zu denken.
InformationsquelleAutor der Antwort
Wenn Sie schreiben eine VM in C, es stellt sich heraus, dass die Verwendung von (gcc) berechnete gotos wie diese:
arbeitet viel schneller als bei der konventionellen switch innerhalb einer Schleife verwenden.
InformationsquelleAutor der Antwort
Weil
goto
kann verwendet werden, für verwirrend metaprogrammingGoto
ist sowohl ein high-level - und ein low-level - Kontrolle Ausdruck, und als ein Ergebnis, es funktioniert einfach nicht einen passenden design-Muster geeignet für die meisten Probleme.Es ist low-level - in dem Sinne, dass ein goto ist eine primitive operation, die etwas höher wie
while
oderforeach
oder so etwas.Es ist high-level - in dem Sinne, dass, wenn verwendet, in gewisser Weise braucht es code, der ausgeführt wird, in eine klare Abfolge, in einer ununterbrochenen Weise, außer für strukturierte Schleifen, und es ändert sich in Stücke von der Logik, sind mit genug
goto
s, ein grab-bag von Logik dynamisch zusammengesetzt werden.So, es ist ein prosaischen und ein böse Seite
goto
.Den prosaischen Seite ist, dass ein aufwärts gerichteter goto implementieren können, ist eine ganz einfache Schleife und ein nach unten zeigendes springen tun können, ein durchaus vernünftiger
break
oderreturn
. Natürlich, eine tatsächlichewhile
break
oderreturn
wäre viel besser lesbar, als die Armen Menschen nicht haben, zu simulieren die Wirkung dergoto
um das große Bild. Also generell eine schlechte Idee.Den böse Seite umfasst eine routine, die nicht mit springen für eine Weile, zu brechen, oder Rückkehr, aber verwenden Sie es für das, was genannt spaghetti Logik. In diesem Fall wird der goto-happy Bauherr code-Stücken, die aus einem Labyrinth von goto ' s, und der einzige Weg zu verstehen, ist es, zu simulieren, es mental als ganzes, eine furchtbar anstrengende Aufgabe, wenn es gibt viele GOTOs. Ich meine, stellen Sie sich die Mühe der Auswertung code, wo die
else
ist nicht genau eine inverse derif
wo verschachtelteif
s ermöglichen könnte, in einigen Dingen, die abgelehnt wurden, von der äußerenif
etc, etc.Schließlich, um wirklich das Thema abdecken, sollten wir beachten, dass im wesentlichen alle frühen Sprachen mit Ausnahme von Algol anfangs nur einzelne Aussagen unterliegen Ihre Versionen von
if-then-else
. Also, der einzige Weg, um eine bedingte blockgoto
um es mit einem umgekehrten bedingten. Verrückt, ich weiß, aber ich habe gelesen, einige alte Spezifikationen. Denken Sie daran, dass die ersten Computer wurden so programmiert ist, in binäre Maschinencode-also ich nehme an, jede Art von einem HLL war ein Lebensretter; ich vermute, Sie waren nicht allzu wählerisch, was genau HLL Funktionen, die Sie bekam.Nachdem alles gesagt, dass ich verwendet, um den stick eines
goto
in jedem Programm, das ich schrieb "einfach nur zu ärgern Puristen".InformationsquelleAutor der Antwort
Leugnen, die Verwendung der GOTO-Anweisung, um die Programmierer zu erzählen ist wie ein Zimmermann nicht mit einem hammer, wie es Kann zu Schäden der Wand, während er hämmert einen Nagel. Ein echter Programmierer Weiß, Wie und Wann ein SPRINGEN. Ich habe dahinter einige dieser so genannten "Strukturierten Programme" ich habe solche Schreckliche code, nur um nicht mit einem GOTO, das ich Schießen konnte der Programmierer. Ok, In der Verteidigung von der anderen Seite, ich habe gesehen, einige echte spaghetti-code zu, und wieder, die Programmierer sollten erschossen zu werden.
Hier ist nur ein kleiner Beispiel-code, den ich gefunden habe.
-----------------------ODER----------------------
InformationsquelleAutor der Antwort
Den ursprünglichen Arbeit sollte verstanden werden als: "Unbedingte GOTO considered harmful". Es war vor allem die Befürwortung einer form von Programmierung basierend auf bedingten (
if
) und iterative (while
) konstruiert, sondern als die test-and-jump gemeinsamen früh-code.goto
ist immer noch nützlich in einigen Sprachen oder Umstände, in denen keine geeigneten Kontroll-Struktur existiert.InformationsquelleAutor der Antwort
"In diesem link http://kerneltrap.org/node/553/2131"
Ironischerweise, wodurch das springen eingeführt, ein Fehler: die spinlock-Aufruf weggelassen wurde.
InformationsquelleAutor der Antwort
Etwa der einzige Ort an dem ich einig Gehe könnte verwendet werden, ist, wenn Sie brauchen, um mit Fehlern umzugehen, und jeder Punkt ein Fehler Auftritt, erfordert Besondere Behandlung.
Zum Beispiel, wenn Sie greifen und Ressourcen mit Semaphoren oder Mutexe, Sie zu greifen, Sie in Ordnung und Sie sollten immer geben Sie in die entgegengesetzte Weise.
Einigen code erfordert eine sehr seltsame Muster greifen diese Ressourcen, und Sie können nicht schreiben Sie einfach ein leicht gepflegt und verstanden control-Struktur korrekt zu behandeln, sowohl das kopieren und die Freigabe dieser Ressourcen, um Deadlocks zu vermeiden.
Ist es immer möglich, das richtige zu tun, ohne zu springen, aber in diesem Fall und ein paar andere Springen ist eigentlich die bessere Lösung, vor allem für die Lesbarkeit und Wartbarkeit.
-Adam
InformationsquelleAutor der Antwort
Einer modernen GOTO-Nutzung ist durch den C# - compiler zum erstellen von Zustandsautomaten für Enumeratoren definiert durch Rendite.
SPRINGEN ist etwas, das verwendet werden soll, die von Compiler und nicht Programmierer.
InformationsquelleAutor der Antwort
Bis C und C++ (unter anderen Täter) gekennzeichnet bricht und weiter geht, springen auch weiterhin eine Rolle.
InformationsquelleAutor der Antwort
Vermeide ich es seit ein Mitarbeiter/manager wird zweifellos die Frage nach deren Verwendung entweder in einem code-review oder, wenn Sie stolpern über Sie. Während ich denke, es hat verwendet (die Fehlerbehandlung Fall zum Beispiel) - Sie werden in Konflikt geraten einige andere Entwickler haben eine Art von problem mit ihm.
Lohnt es sich nicht.
InformationsquelleAutor der Antwort
Wenn SPRINGEN selbst böse waren, Compiler wäre böse, denn Sie erzeugen JMPs. Sollte das springen in einen block von code, insbesondere nach einem Zeiger, waren von Natur aus böse, die RETurn-Anweisung wäre böse. Sondern das böse ist das Potenzial für Missbrauch.
Manchmal musste ich das schreiben von apps, die musste im Auge behalten eine Anzahl von Objekten, wobei jedes Objekt zu befolgen hatten eine komplizierte Abfolge von Staaten, die in Reaktion auf Ereignisse, aber die ganze Sache war auf jeden Fall single-thread. Eine typische Abfolge von Staaten, wenn dargestellt in pseudo-code wäre:
Ich bin sicher, dies ist nicht neu, aber die Art, wie ich behandelt es in C(++) zu bestimmen, einige Makros:
Dann (vorausgesetzt, Zustand ist anfangs 0) der strukturierte state-Maschine über dreht sich in der strukturierten code:
Mit einer variation davon, es kann sein CALL und RETURN, so dass einige state-Maschinen handeln können, wie Unterprogramme von anderen staatlichen Maschinen.
Ist es ungewöhnlich? Ja. Es dauert einige lernen seitens der Betreuer? Ja. Nicht, dass sich das lernen lohnen? Ich denke, so. Könnte es getan werden, ohne GOTOs, die den Sprung in die Blöcke? NÖ.
InformationsquelleAutor der Antwort
Ich eigentlich mich gezwungen, eine springen, weil ich buchstäblich konnte nicht glauben, eine bessere (schnellere) Weg, um dieser code zu schreiben:
Hatte ich ein Komplexes Objekt, und ich brauchte eine operation auf Sie. Wenn das Objekt in einem Zustand ist, dann könnte ich tun, eine schnelle version der operation, da ich sonst zu tun hatte, eine langsame version der operation. Die Sache war, dass in einigen Fällen, in der Mitte der langsamen Betrieb, war es möglich, zu erkennen, dass dies hätte getan werden können, mit der schnellen Bedienung.
Diese wurde in einem speed-kritische Stück von Echtzeit-code der Benutzeroberfläche, so dass ich ehrlich glaube, dass ein GOTO war gerechtfertigt hier.
Hugo
InformationsquelleAutor der Antwort
Fast alle Situationen, in denen ein goto verwendet werden kann, können Sie das gleiche tun mit anderen Konstrukten. Goto wird verwendet, indem der compiler sowieso.
Ich persönlich benutze es nie explizit, nicht immer müssen.
InformationsquelleAutor der Antwort Adam Houldsworth
Eine Sache, die ich nicht gesehen hab von alle von den Antworten hier ist, dass eine 'goto' - Lösung ist oft effizienter als einer der strukturierten Programmierung Lösungen oft erwähnt.
Viele verschachtelte-Schleifen-Fall, wo mithilfe von 'gehe zu' - anstelle einer Reihe von
if(breakVariable)
Abschnitten ist offensichtlich effizienter. Die Lösung "Setzen Sie Ihre Schleifen in einer Funktion return" ist oft völlig unsinnig. Im wahrscheinlichen Fall, dass die Schlaufen sind mit lokalen Variablen, die Sie jetzt haben, übergeben Sie alle durch die Funktion Parameter, die potenziell den Umgang mit Lasten der zusätzlichen Kopfschmerzen, die daraus entstehen.Betrachten Sie nun das cleanup-Fall, die ich verwendet habe, mich sehr oft, und ist so verbreitet wie haben vermutlich verantwortlich für die try{} catch {} - Struktur nicht verfügbar in vielen Sprachen. Die Anzahl der Prüfungen und die zusätzlichen Variablen, die erforderlich sind, um das gleiche erreichen, sind weit schlimmer als die ein oder zwei Anweisungen, um das springen, und wieder, die die zusätzliche Funktion der Lösung ist nicht eine Lösung überhaupt. Sie können mir nicht sagen, dass mehr überschaubar oder mehr lesbar.
Nun code space, stack-Nutzung, und die execution time kann es nicht egal genug, in vielen Situationen zu viele Programmierer, aber wenn man in einer embedded-Umgebung mit nur 2KB code-Speicherplatz, mit zu arbeiten, 50 Byte zusätzliche Anweisungen zu vermeiden, eine klar definierte 'goto' ist einfach nur noch lächerlich, und das ist nicht so selten eine situation, als viele high-level-Programmierer glauben.
Die Aussage, dass 'goto ist schädlich" war sehr hilfreich auf dem Weg zur strukturierten Programmierung, auch wenn es immer eine Verallgemeinerung. An diesem Punkt, wir haben alle gehört, reicht es, vorsichtig sein, mit (wie wir sollten). Wenn es natürlich das richtige Werkzeug für den job, wir brauchen nicht zu Angst, es.
InformationsquelleAutor der Antwort
Können Sie es verwenden, für das brechen aus einer tief verschachtelten Schleife, aber die meisten der Zeit, Ihren code umgestaltet werden kann sauberer sein, ohne tief verschachtelte Schleifen.
InformationsquelleAutor der Antwort