PDA

View Full Version : [C] GOTO


Akali
07-11-2015, 21:28
Sera tutti, mi potete spiegare le principali ragioni per cui si odia così tanto il GOTO? Io credo che se lo si utilizza in maniera intelligente qualcosa di buono ci ricavi. Anche molti docenti ne hanno quasi proibito l'uso (alcuni minacciando una bocciatura istantanea) mentre altri dicono che un corretto utilizzo possa solo giovare. Chi ha ragione quindi secondo voi?

Daniels118
08-11-2015, 01:22
Il motivo per il quale si sconsiglia di utilizzare il goto è che esso rende il codice destrutturato e di conseguenza più difficile da interpretare. In pratica quando osservi un algoritmo correttamente formattato (indentato) riesci subito ad individuare dei blocchi di codice ed hai la certezza che a run time quando entri in un blocco questo viene eseguito fino alla fine, quindi l'esecuzione riprende dall'istruzione successiva o dall'inizio del blocco se si tratta di un ciclo; se invece nel blocco è presente un goto il flusso di esecuzione potrebbe saltare in un punto completamente diverso del programma, per questo occorre molto più impegno per comprendere la logica che c'è dietro. D'altra parte però il goto insieme ad altre istituzioni (break e return) consente di gestire in maniera più intuitiva le condizioni di eccezione, ovvero quelle condizioni in cui l'esecuzione dell'algoritmo non è più necessaria (perché i dati sono compromessi oppure si è giunti alla soluzione prima del previsto). In java ad esempio è stato creato un ibrido per rendere strutturata la gestione delle eccezioni attraverso il costrutto try catch e l'istruzione throw, che di fatto esegue un salto proprio come il goto.

lorenzo001
08-11-2015, 11:15
Non capisco Akali ... perché la risposta di Daniels118 viene riportata tale e quale a nome di un altro utente in altro forum

http://www.inforge.net/xi/threads/c-goto-che-ha-fatto-di-male.439664/#post-4355472

Fai la domanda qui e la riporti su Inforge? Che comportamento è questo?

E poi un "ingegnere elettronico" (nell'altro forum sei "laureato in informatica") che fa queste domande !

Forse la tua vera età spiega questo comportamento infantile ...

das
10-11-2015, 11:52
Dipende da quello che vuoi fare. Se vuoi che il codice sia facilmente riutilizzabile in altri contesti il goto può essere un ostacolo.

Se scrivi del codice per te e vuoi ottenere il risultato nel minor tempo possibile senza scervellarsi troppo, allora lo puoi usare.

Personalmente penso la gente (tipo i tuoi prof) si fissi con delle regole e poi diventa matta per rispettarle. In realtà non esistono regole, dipende sempre da quello che vuoi fare.

Per quanto riguarda la comprensibilità del codice allora le funzioni ricorsive sono molto peggio del goto, eppure sono universalmente riconosciute come esempio di eleganza e bravura.

fano
13-11-2015, 21:28
Forse l'unico caso in cui il goto è giustificabile è quando, come diceva Daniels118 è successo un errore "irrecuperabile" (in "veri" linguaggi di programmazioni sono appunto chiamate eccezioni!) e uno fa un goto end e nella label end fai il clean up. Nel mio team di lavoro sono vietate e quindi si fa return quando l'errore irrecuperabile accade si fa prima il clean up il problema di questo approccio e che, a volte, per la sfrescia di fare return il codice di clean up ci se lo dimentica.

Detto questo anche se il codice te lo scrivi per il tuo uso e consumo cerca di non usare il goto pensaci bene magari chiamando una funzione avresti un codice più bello e non ti troveresti a far "pasticci"?

Per esempio ecco come fare per non prendersela nello stoppino con clean up & return:


int my_func(void)
{
[...]
char *test = malloc(); // ma può essere anche una (f)open o una qualunque risorsa che devi liberare
int rc;
rc = do_something_with_test();
// Che abbia funzionato o no liberiamo 'test'
free(test);
if (rc != 0)
combust(); // Siamo fritti!

return rc;
}


Le ultime versione del C hanno le embedded function (simili alle lambda functions e alle closure di altri linguaggi):


int my_func(void)
{
[...]
char *test = malloc(); // ma può essere anche una (f)open o una qualunque risorsa che devi liberare

int do_something_with_test(void) {
[...]
}

int rc;
rc = do_something_with_test();
// Che abbia funzionato o no 'test' non serve più
free(test);
if (rc != 0)
combust(); // Siamo fritti!

return rc;
}


Purtroppo per quante sia una "bella" soluzione quella di creare una embedded function non la consiglio non è - stranamente - compatibile con il C++ e questo a me ha morso le chiappe (ero così ingorillato e poi...) :doh:

P.S. Non pensare che goto sia più ottimizzato che chiamare una funzione! Questi ragionamenti deve farli il compilatore... se proprio vuoi dichiara do_something_with_test() come static inline così stai sereno :D