Domanda

goto è quasi universalmente scoraggiato. Sta usando questa affermazione sempre vale la pena?

È stato utile?

Soluzione

Questo è stato discusso più volte su Stack Overflow, e Chris Gillum riassunto i possibili usi di goto :

Cleanly uscire da una funzione

Spesso, in una funzione, è possibile allocare le risorse e necessità di uscire in più posti. I programmatori possono semplificare il loro codice mettendo il codice di pulitura risorse alla fine della funzione Tutto tutti i "punti di uscita" della funzione farebbero goto etichetta pulitura. In questo modo, non è necessario scrivere il codice di pulitura in ogni "punto di uscita" della funzione.

Uscita annidati loop

Se sei in un ciclo nidificato e necessità di uscire dalla tutti loop, un goto può fare questo molto più pulito e più semplice di istruzioni break e se-controlli.

miglioramenti prestazioni di basso livello

Questo è valido solo nel codice perf-critico, ma goto dichiarazioni eseguire molto rapidamente e può dare una spinta quando si muove attraverso una funzione. Questa è una spada a doppio taglio, però, perché un compilatore in genere codice non può ottimizzare che contiene goto.

Direi, come molti altri sostengono, che in tutti questi casi, l'utilizzo di goto è usato come mezzo per uscire da un angolo uno codificato se stessi in, ed è generalmente un sintomo di codice che potrebbe essere riscritta.

Altri suggerimenti

di controllo di livello superiore costrutti flusso tendono a corrispondere ai concetti nel dominio del problema. Un if / else è una decisione basata su una certa condizione. Un ciclo dice per eseguire ripetutamente una certa azione. Anche un'istruzione break dice "che stavamo facendo questo più volte, ma ora abbiamo bisogno di stop".

Un goto dichiarazione, d'altra parte, tende a corrispondere a un concetto del programma in esecuzione, non nel dominio del problema. Si dice di continuare l'esecuzione in un punto specificato nel programma . Qualcuno la lettura del codice deve inferire che cosa significa rispetto al dominio del problema.

Naturalmente tutti i costrutti di livello superiore possono essere definite in termini di GOTOS e semplici salti condizionati. Ciò non significa che essi sono semplicemente goto sotto mentite spoglie. Pensare a loro come limitato goto - ed è le limitazioni che li rendono utili. Un'istruzione break è implementato come un salto alla fine del ciclo racchiude, ma è meglio pensato come operare sul circuito nel suo complesso.

Tutti essere parità di altre condizioni, il codice la cui struttura riflette quella del dominio del problema tende ad essere più facile da leggere e gestire.

Non ci sono casi in cui è assolutamente necessario un goto (c'è un teorema in tal senso), ma ci sono casi in cui può essere la soluzione meno peggio. Questi casi variano da una lingua all'altra, a seconda di ciò che di più alto livello costruisce il supporto per il linguaggio.

In C, per esempio, credo che ci sono tre scenari di base in cui un goto è appropriato.

  1. Scoppio di un ciclo nidificato. Questo sarebbe inutile se la lingua ha avuto un'istruzione break etichettata.
  2. Bailing su un tratto di codice (tipicamente un corpo di funzione) in caso di errore o altri eventi imprevisti. Questo sarebbe inutile se la lingua aveva eccezioni.
  3. Implementazione di una macchina a stati finiti esplicito. In questo caso (e, credo, solo in questo caso) un goto corrisponde direttamente ad un concetto nel dominio del problema, la transizione da uno stato ad un altro stato specificato, dove lo stato attuale è rappresentato dal quale blocco di codice è attualmente in esecuzione .

D'altra parte, una macchina a stati finiti esplicito può essere realizzata anche con un'istruzione switch all'interno di un ciclo. Questo ha il vantaggio che ogni stato inizia nello stesso punto del codice, che può essere utile per il debugging, per esempio.

L'utilizzo principale di un goto in una lingua abbastanza moderno (uno che supporti if / else e loop) è quello di simulare un costrutto flusso di controllo che manca dalla lingua.

Sicuramente dipende dal linguaggio di programmazione. Il motivo principale goto è stato controverso a causa della sua effetti negativi che si presentano quando il compilatore permette di usare troppo liberamente. I problemi possono sorgere, ad esempio, se si consente di utilizzare goto in tal modo un che ora è possibile accedere a una variabile Non inizializzato, o peggio, di saltare in un altro metodo e la mensa con lo stack di chiamate. Dovrebbe essere responsabilità del compilatore per non consentire il flusso di controllo priva di senso.

Java ha cercato di “risolvere” il problema vietando goto del tutto. Tuttavia, Java consente di utilizzare return all'interno di un blocco finally e quindi causare un'eccezione da inavvertitamente ingerito. Lo stesso problema è ancora lì: il compilatore non sta facendo il suo lavoro. Rimozione goto dalla lingua non è risolto.

In C #, goto è sicuro come break, continue, try/catch/finally e return. Essa non consente di utilizzare le variabili non inizializzate, ma non consente di saltare da un blocco finally, ecc Il compilatore si lamenta. Questo perché risolve il reale problema, che è come ho detto flusso di controllo senza senso. goto non magicamente annullare l'analisi definitiva assegnazione e altri controlli ragionevole compilatore.

Sì. Quando i loop sono annidati diversi livelli di profondità, goto è il solo modo di elegantemente rottura di un ciclo interno. L'altra possibilità è quella di impostare un flag e rompere ogni ciclo se quella bandiera soddisfa una condizione. Questo è veramente brutto, e piuttosto soggetto a errori. In questi casi, goto è semplicemente migliore.

Naturalmente, dichiarazione break etichettata di Java fa la stessa cosa, ma senza permettere di passare a un punto arbitrario nel codice, che risolve il problema ordinatamente senza che le cose che fanno male goto.

La maggior parte del scoramento arriva formare una sorta di "religione" che è stato creato aroud Dio Djikstra che era convincente nei primi anni '60 su di esso è il potere indiscriminato a:

  • saltare ovunque in qualunque blocco di codice
    • funzione non eseguita fin dall'inizio
    • non loop eseguito dall'inizio
    • saltato inizializzazione delle variabili
  • saltare lontano da qualsiasi blocco di codice senza possibilità di pulizia.

Questo non ha nulla a che fare con l'affermazione goto delle lingue moderne, la cui esistenza è semplicemente dovuto a sostenere la creazione di strutture di codice diverse da quelle fornite in lingua.

In particolare il primo punto principale di cui sopra è più consentito e il secondo è pulito (se goto da un blocco della pila è unwinded correttamente e tutti i distruttori corrette chiamato)

È possibile fare riferimento questa risposta per avere un'idea di come anche il codice non usare goto può essere illeggibile. Il problema non è in sé Goto, ma il cattivo uso di esso.

posso scrivere un intero programma senza utilizzare if, appena for. Certo, non sarà ben leggibile, un goffo aspetto e inutilmente complicato.

Ma il problema non è for. Sono io.

Cose come break, continue, throw, bool needed=true; while(needed) {...}, ecc stanno notando più di mascherata goto per sfuggire dalle scimitarre degli Zeloti Djikstrarian, che -50 anni dopo l'invenzione della moderna laguages- vogliono ancora i loro prigionieri. Hanno dimenticato che cosa Djikstra stava parlando, si ricordano solo il titolo della sua nota (GOTO considerato nocivo, e non era nemmeno il suo titolo onw: è stato cambiato dal curatore) e la colpa e bash, bash e la colpa ogni contruct avere quei 4 lettera messo in sequenza.

E '2011:. E' tempo di capire che goto è nota a che fare con l'affermazione GOTO Djikstra era convincente circa

Il goto dispari qui o là, fino a quando è locale a una funzione, raramente danneggia in modo significativo la leggibilità. Spesso benefici che attirando l'attenzione sul fatto che ci sia qualcosa di insolito in corso in questo codice che richiede l'utilizzo di una struttura di controllo un po 'fuori dal comune.

Se (locali) goto stanno danneggiando notevolmente la leggibilità, quindi di solito è un segno che la funzione di contenimento del goto è diventata troppo complessa.

L'ultima goto ho messo in un pezzo di codice C era quello di costruire un paio di anelli di collegamento. Non si adatta nella normale definizione di uso goto "accettabili", ma la funzione finito significativamente più piccolo e più chiaro in seguito. Per evitare il goto avrebbe richiesto una violazione particolarmente disordinato di SECCO.

Credo che l'intera questione è stato un caso di abbaiare contro l'albero sbagliato.

GOTO come tale non sembra problematico per me, ma è molto spesso un sintomo di un peccato attuale: spaghetti code

.

Se il GOTO causa principale attraversamento di linee di controllo di flusso, allora è cattivo, periodo. Se si attraversa senza linee di controllo di flusso è innocuo. Nella zona grigia intermedia abbiamo cose come salvataggi di loop, ci sono ancora alcune lingue che non sono costrutti che coprono tutti i casi di grigio legittime aggiunto.

L'unico caso che ho trovato me stesso in realtà di utilizzarlo in molti anni è il caso del ciclo in cui il punto di decisione è nel mezzo del ciclo. Si è lasciato con uno codice duplicato, una bandiera o un GOTO. Trovo la soluzione GOTO il migliore dei tre. Non v'è alcun incrocio di linee di controllo del flusso qui, è innocuo.

Sì, il goto può essere utilizzato per beneficiare l'esperienza dello sviluppatore: http://adamjonrichardson.com/2012/02/06/ -viva-la-goto-statement /

Tuttavia, proprio come con qualsiasi strumento potente (puntatori, l'ereditarietà multipla, ecc), si deve essere disciplinato utilizzarlo. L'esempio fornito nel collegamento utilizza PHP, che limita l'uso del costrutto goto alla stessa funzione / metodo e disabilita la possibilità di saltare in un nuovo blocco di controllo (ad esempio, loop, switch, ecc.)

dipende dalla lingua. E 'ancora ampiamente usato in programmazione Cobol, per esempio. Ho anche lavorato su un dispositivo Barionet 50, il cui linguaggio di programmazione firmware è un dialetto BASIC precoce che, naturalmente, si richiede di utilizzare Goto.

I non sarebbe dire. Se si trova la necessità di utilizzare GOTO, scommetto che c'è un bisogno di ridisegnare il codice.

goto può essere utile quando porting codice legacy Assembler a C. In primo luogo, una conversione istruzione per operazione a C, utilizzando goto come sostituto per l'istruzione branch del assemblatore, può attivare molto rapido porting.

Vorrei non discutere. Essi devono sempre essere sostituiti con uno strumento più specifico per il problema del goto viene utilizzato per risolvere (a meno che non è disponibile nella tua lingua). Ad esempio, istruzioni break ed eccezioni risolvere i problemi precedentemente goto-risolti di ciclo fuggire e gestione degli errori.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
scroll top