Newsgroup: it.comp.lang.c
Titolo: Goto

Ciao.
Ho gia' alzato gli scudi, perche' penso mi arriveranno tanti missili ;-).
Sto leggendo un testo. Parlando di questa istruzione dice:
"E' difficile infatti descrivere in termini generali una situazione in cui
e' effettivamente necessario usare 
goto.se
 non nei casi in cui tale uso
rende il codice piu' efficiente o ne aumenta la leggibilita'. Per una
trattazione completa si rimanda al libro 'Goto Statement Considered
Harmful'".
Ci sono veramente dei casi dove goto batte tutti 1 a 0?
Chi mi puo' fare degli esempi?
Igor Rossetti


Ciao,
in effetti goto e' inelegante ma a volte indispensabile. Io devo
interfacciare degli interrupt in assembler attraverso funzioni C.  Il motivo
si puo' ricondurre al fatto che l'istruzione Return To Interrupt non e'
disponibile in C e quindi si deve raggiungere la funzione di interrupt
solamenre con la 'goto'.
L'unico problema che ho, e se qualcuno mi rispondesse ne sarei grato, e' che
la label deve essere nello stesso modulo in cui viene richiamata e non in un
modulo esterno (ad esempio modulo Assembler). Oltretutto non riesco a
dichiarare una label extern.
Roberto Palmarin
r_pal...@microdata-em.it

Chi mi puo' fare degli esempi?
Un esempio e' quello dell'uscita da una serie di loop annidati:
while( ... ) {
  while( ... ) {
    while( ... ) {
      goto Ciao;
..}}}
Ciao:
In effetti proprio per i loop ci sono istruzioni come "break" e "continue" che 
sono dei "goto" sotto mentite spoglie, ma ovviamente piu' leggibili e 
"sicuri".
Comunque la frase "E' difficile infatti descrivere in termini generali una 
situazione in cui e' effettivamente necessario usare goto se non nei casi in 
cui tale uso rende il codice piu' efficiente o ne aumenta la leggibilita'" mi 
sembra alquanto tautologica, dal momento che e' in pratica l'equivalente di 
"e' difficile descrivere una situazione in cui e' necessario usare XXXX se non 
nei casi in cui e' meglio".
P.S. Il libro "Algoritmi+Strutture Dati=Programmi" di N. Wirth contiene delle 
istruzioni "goto" anche in qualche listato (in Pascal)... ma se ricordo 
bene Oberon, un successivo linguaggio/ambiente di Wirth, non ha il "goto".

 Chi mi puo' fare degli esempi?
Normalmente si trova questo:
for ( i = 0; i < n; i++ )
{
    ...
    for ( j = 0; j < m; j++ )
    {
        ...
        if ( ... ) goto esci;
        ...
    }
}
esci:
...
EMG

 dichiarare una label extern.
in c non si può fare salti extrasegmentali come in assembler ?

 wrote in message
1e2r49t.lp...@ppp-20-12-250.libero.it...

Scusami e' una domanda o un'affermazione? Nel mio caso ho diversi moduli, e
vorrei fare salti 'goto' tra di loro.
Ciao e Grazie



dichiarare una label extern.
Non puoi, se non ricordo male, le label hanno "scope" limitato al
blocco di codice di funzione.
--
Andrea Laforgia
andrea_...@bigfoot.com

Ci sono veramente dei casi dove goto batte tutti 1 a 0?
Non credo proprio.
Tutto quello che si puo' fare con i goto e' fattibile per via
strutturata.
--
Andrea Laforgia
andrea_...@bigfoot.com

esci:
Be', ma non e' che sia una situazione in cui batte tutti 1 a 0 :
for ( i = 0; i < n ; i++ )
{
    ...
    for ( j = 0; j < m ; j++ )
    {
        ...
        if ( ... ) break ;
        ...
    }
    if ( ... ) break ;
}
oppure, se non si vuole utilizzare "break" che e' comunque un goto :
for ( i = 0; i < n && (condizione_permanenza) ; i++ )
{
    ...
    for ( j = 0; j < m (condizione_permanenza) ; j++ )
    {
        ...
        if ( condizione permanenza )
        { 
            ...
        }
    }
}
--
Andrea Laforgia
andrea_...@bigfoot.com

nei casi in cui e' meglio".
Be' pero', effettivamente, descrive in quali casi e' meglio.
In effetti e' un po' contorta e avrebbero potuto formularla come :
"L'istruzione goto non e' quasi mai necessaria, tranne quando serva a
rendere il codice piu' efficiente o piu' leggibile".
Ma ho i miei dubbi su questa "necessarieta'", sulla maggiore
leggibilita' del codice ed anche riguardo l'efficienza non sono cosi'
convinto.
--
Andrea Laforgia
andrea_...@bigfoot.com

solamenre con la 'goto'.
Scusami, ma chi l'ha detto che non e' disponibile ?
Che compilatore usi ?
--
Andrea Laforgia
andrea_...@bigfoot.com

 Ciao e Grazie
Due funzioni (e non istruzioni) standard permettono di gestire salti
tra moduli: setjmp() e longjmp(). Possono anche uscire da una funzione
e rientrare nella funzione chiamante. Se la funzione e' gia' terminata
(nei casi in cui farjump() e' chiamata in un handler di segnale),
non e' definito alcun comportamento.
Sono molto sofisticate, e anche se non bisogna farne uso dissoluto
perche'
sempre si tratta di programmazione non strutturata, si possono gestire
le
eccezioni in modo preciso come in C++.
E' definita una struttura dati jmp_buf destinata a contenere l' immagine
del programma in quel momento. I componenti non sono accessibili in modo
standard.
Chiamando:
setJmp(jmpbuf);  /* setti jmpbuf di tipo jmp_buf all 'immagine del progr
*/
Il codice seguente deve valutare se il valore restituito (di tipo int)
e' 0 o 1. se 0 e' la prima chiamata, se 1 allora siamo ritornati da un
longjmp();
In piu' punti del codice puoi chiamare setjmp settando diverse var di
tipo
jmp_buf e in altri punti chiamando;
longjmp(jmpbuf);
ritorni al punto done quel buffer e' stato settato.
Si conclude che queste due funzioni sono un po' atipiche: setjump
puo' ritornare due volte a seguito di una chiamata e longjmp 
se tutto va correttamente non ritorna, perche' trasferisce il controllo
a programma nel punto di chiamata a setjmp.
Use with care!!
ciao.

 dichiarare una label extern.
Non ricordo bene perché non l'ho mai utilizzato, ma prova a guardare se
setjmp()/longjmp() ti possono essere utili.
EMG

 bene Oberon, un successivo linguaggio/ambiente di Wirth, non ha il "goto".
Infatti neanche il Clipper (linguaggio da me utilizzato) dispone del
goto ma io non ne ho mai sentito la necessità.
EMG

 Be', ma non e' che sia una situazione in cui batte tutti 1 a 0 :
[ snip ]
Non sono d'accordo: in termini di pura efficienza, la soluzione 
che usa la goto per uscire da più cicli nidificati è migliore.
Ciao ciao,
Andrea
-- 
"...Unix, MS-DOS, and Windows NT (also known as the Good, the Bad, and 
 the Ugly)."
(by Matt Welsh)


Beh, se e' per questo io non ho mai sentito nemmeno la necessita' del 
Clipper... :-)

 Ci sono veramente dei casi dove goto batte tutti 1 a 0?
A livello teorico ho studiato che qualunque algoritmo si puo'
risolvere attraverso i costrutti fonamentali della programmazione
strutturata. Quindi credo che sia meglio imparare a non usare il goto.
Ormai sembra quasi che sia un tabu' l'uso del goto(bella la rima;-))!!!)
Pero', anche se io non ho mai avuto il bisogno di provarlo, credo che dei
casi
utili, come uscire da + cicli innestati, esistano.
Anche se puoi evitarlo...e gli esempi di sono stati fatti da gente + esperta
di me;)))
--
 Byez By Roby "Offear" '82
 Unofficial Blind Guardian's Site:
 
http://surf.to/Blindguardian
 Mi raccomando visitatela!!!!!!!!

 Clipper... :-)
Forse perché non lo conosci...
EMG

 Chi mi puo' fare degli esempi?
...
for (...)
    for (...)
        for (...)
            for (...)
                for (...){
                    if (...)
                        goto esci;
                }
esci:
...
Anche se personalmente non mi è mai capitato di usarlo in C, C++ o in
Pascal.
--
Alessandro Monti

 rendere il codice piu' efficiente o piu' leggibile".
Perchè il quasi?
Esiste persino un teorema sull'eliminabilità del goto.
Diciamo invece che il goto rende *sempre* il codice poco leggibile, ma ci
sono i casi in cui le alternative sono ancora meno leggibili :-)
--
Alessandro Monti

 goto ma io non ne ho mai sentito la necessità.
Sei sicuro? A me pare di ricordare che invece ci sia.
A proposito, usi ancora il Clipper? Io non l'ho mai amato, a parte quel
goiello che erano i "code-block"... ma era sempre meglio di altri linguaggi
più moderni.
--
Alessandro Monti

Alessandro Monti ha scritto nel messaggio
<15z54.1263$RQ.1...@news.infostrada>...

Ti capita se devi sviluppare 13 triple al totocalcio.
Io faccio:
for (...)
    for (...)
        for (...)
            for (...)
                for (...){
                    if (...)
                    {
                        resto_della_procedura();
                        return;
                    }
                }
    resto_della_procedura();
}
Pero' in effetti in questi casi il goto forse e' accettabile.
Marco


Se lo conosci lo eviti.
..ohe' era una battuta... non ti inalberare! Come ogni linguaggio 
avra' i suoi pregi e i suoi difetti, ma certamente non volevo metterlo in 
discussione!

 
Per quel che ne so, in assembly verrebbe comunque tradotta con un bel
_branch_ 
 Ciao, Luca.
 Reply to 
luca....@tiscalinet.it

 Sei sicuro? A me pare di ricordare che invece ci sia.
C'è come keyword ma significa "vai al record numero...".
EMG

 Pero' in effetti in questi casi il goto forse e' accettabile.
Lo dicono K & R. :-)
EMG

 ..ohe' era una battuta... non ti inalberare!
Non mi ero inalberato.
EMG

 _branch_ 
?


     for (...)
...
Si, ma allora preferisco implementarlo con altri trucchetti, in modo che se
le colonne diventano 12 o 14 non devo modificare il codice (o non troppo).
Ciò capiterà difficilmente con il totocalcio, ma la procedura torna utile
anche per altri giochi.
E non serve il goto :-)
--
Alessandro Monti

}
Me ne intendo veramente poco, pero' non e' che, in termini di velocita' di
esecuzione, un goto e' piu' efficiente di due if ?
Voglio dire, il compilatore tradurra' il goto con un "jump", mentre per i
confronti impieghera' piu' istruzioni (premetto che non conosco l'assembler
dell' X86).
Saluti
Igor Rossetti

Esiste persino un teorema sull'eliminabilità del goto.
Infatti l'ho detto, tutto cio' che e' possibile fare mediante goto e'
parimenti fattibile mediante le strutture iterative.
--
Andrea Laforgia
andrea_...@bigfoot.com

più moderni.
Siete/amo OT, comunque non credo che un linguaggio si usi solo perche'
lo si ama. E' probabile che per esigenze di lavoro si sia costretti ad
utilizzare un linguaggio particolare.
Il Clipper e' un linguaggio (come il COBOL) destinato alla scrittura
di applicativi gestionali e *da questo punto di vista* e' sicuramente
meglio di altri linguaggi, ma non credo siano molti i linguaggi
"battibili" in assoluto.
--
Andrea Laforgia
andrea_...@bigfoot.com

esecuzione, un goto e' piu' efficiente di due if ?
La maggiore efficienza e' innegabile ma non si sta parlando
prettamente di questo. EMG ha citato il caso in cui, secondo la sua
opinione, il goto batte tutti 1 a 0 (per usare le parole dell'autore
del msg originale). Io sto solo cercando di mettere in luce che il
goto non e' realmente necessario, nonostante ci sia effettivamente un
miglioramento nell'efficienza. Credo, comunque, che un programmatore
non badi (generalmente) soltanto all'efficienza del codice. O sbaglio


le colonne diventano 12 o 14 non devo modificare il codice (o non troppo).
hmmm.. sento odore di ricorsione..:)
Non lo faccio mai per la velocita'. Gia' le colonne sono tante di suo (pensa
all'enalotto) che almeno la generazione deve essere velocina..
In uno dei prg (era richiesta velocita') l'ho dovuto codificare in asm.
E li' i goto (o meglio, jmp a spaghetti) li ho usati a manica.
Ma tanto non mi ha visto nessuno..;-)
Marco

leggibilita' del codice
if (pippo())
   goto gestione_errore;
//codice 
if (pluto())
   goto gestione_errore;
//codice
if (paperino())
{
   assert(0); 
   goto gestione_errore;
}
return tutto_ok;
gestione_errore:
//gestisco i problemi
return tutto_ko;
Mi sembra codice leggibile, e (per me) accettabile.
-------------------------------------------------------
Tieni per te il Papero se vuoi la mia email
Sito Papero -> 
http://utenti.tripod.it/papero

all'enalotto) che almeno la generazione deve essere velocina..
Non e' detto che la ricorsione riduca la velocita' d'esecuzione.
C'e' modo e modo di implementarla, non credi ?
--
Andrea Laforgia
andrea_...@bigfoot.com

Mi sembra codice leggibile, e (per me) accettabile.
Non stiamo parlando di casi specifici, e' indubbio che generalmente il
goto generi una scarsa leggibilita' del codice.
--
Andrea Laforgia
andrea_...@bigfoot.com

C'e' modo e modo di implementarla, non credi ?
Si, ma in genere e' piu' lenta dell'iterazione.
La uso quando la velocita' non e' essenziale, oppure quando altrimenti il
codice diventerebbe troppo illeggibile.
Marco

 
Intendevo una instruzione di salto condizionato.


 Intendevo una instruzione di salto condizionato.
Scusa, ma continuo a non capire cosa c'entri con la mia affermazione 8-?


 opinione, il goto batte tutti 1 a 0 
Infatti. E nel caso dell'uscita da più cicli nidificati, se è necessaria 
la massima efficienza, il goto vince chiaramente.
Se la massima efficienza non serve, allora non ha senso usare il goto.


> hmmm.. sento odore di ricorsione..:)
Nessuna ricorsione, solo uno stack "simulato" tramite un vettore allocato
dinamicamente.
E' un po' come la trasformazione di un algoritmo ricorsivo come qsort in
forma iterativa, solo che in questo caso è piuttosto facile, e tutto sommato
potrebbe anche essere più efficente di una serie di for.
Del resto, qui non si sta eliminando la ricorsione, ma solo una serie fissa
ed immutabile di for in un algoritmo (iterativo) più flessibile.
--
Alessandro Monti

 utilizzare un linguaggio particolare.
E chi ha detto il contrario?
Ho usato Clipper per tutto il tempo che ho ritenuto necessario farlo, senza
piangere troppo.
Aveva dei vantaggi molto evidenti su molti fronti, e dove non arrivava si
poteva certaemnte usare un po' di C/C++.
Però non mi piaceva, mentre invece apprezzo di più uno dei suoi successori
che uso quotidianamente: VFP.
--
Alessandro Monti

codice diventerebbe troppo illeggibile.
Quindi l'odore di ricorsione e' quasi un profumo, no ? :))
--
Andrea Laforgia
andrea_...@bigfoot.com

Due funzioni (e non istruzioni) standard permettono di gestire salti
tra moduli: setjmp() e longjmp(). Possono anche uscire da una funzione
e rientrare nella funzione chiamante. Se la funzione e' gia' terminata
(nei casi in cui farjump() e' chiamata in un handler di segnale),
non e' definito alcun comportamento.
Sono molto sofisticate, e anche se non bisogna farne uso dissoluto
perche'
sempre si tratta di programmazione non strutturata, si possono gestire
le
eccezioni in modo preciso come in C++.
E' definita una struttura dati jmp_buf destinata a contenere l' immagine
del programma in quel momento. I componenti non sono accessibili in modo
standard.
Chiamando:
setJmp(jmpbuf);  /* setti jmpbuf di tipo jmp_buf all 'immagine del progr
*/
Il codice seguente deve valutare se il valore restituito (di tipo int)
e' 0 o 1. se 0 e' la prima chiamata, se 1 allora siamo ritornati da un
longjmp();
In piu' punti del codice puoi chiamare setjmp settando diverse var di
tipo
jmp_buf e in altri punti chiamando;
longjmp(jmpbuf);
ritorni al punto done quel buffer e' stato settato.
Si conclude che queste due funzioni sono un po' atipiche: setjump
puo' ritornare due volte a seguito di una chiamata e longjmp 
se tutto va correttamente non ritorna, perche' trasferisce il controllo
a programma nel punto di chiamata a setjmp.
Use with care!!
ciao.

sono i casi in cui le alternative sono ancora meno leggibili :-)
Se il nome della label e' leggibile, non vedo come il goto possa non esserlo
(a meno che non ce ne siano parecchi)...
Certo che se chiamiamo le label "qua" e "la'"... ;-)
Saluti,
    Mardy

 (a meno che non ce ne siano parecchi)...
Il problema non è tanto nella label, ma nella mancata utilizzazione dei
costrutti introdotti nei linguaggi procedurali.
E' noto che i costrutti di selezione, ripetizione et similia sono da
preferirsi al codice "a spaghetti", per motivi vari, non ultima la
possibilità di effettuare dei controlli di correttezza a run-time.
Ciò non vuole dire certo che se in un mio programma inserisco 1 solo goto
che si riferisce all'etichetta posta 2 righe sotto nel codice, sto mettendo
in crisi chi leggerà il codice. Il problema è che, dove non è inutile,
danneggia la leggibilità del codice.
Se poi si vuole sostenere che il codice assembler è leggibilissimo, se si
mettono i nomi giusti delle variabili e dei salti, allora si sta parlando
d'altro (livello di competenza nel linguaggio, ecc.), ma non certo di
criteri generali normalmente accettati per la codifica dei programmi.
Il goto è totalmente estraneo alla filosofia di programmazione dei linguaggi
procedurali, pure se ammesso, e pertanto se ne dovrebbe fare uso con estrema
cautela. E a mio avviso non basta neanche dire "se c'è, è da usarsi come
qualsiasi altra istruzione", perchè allora anche per i cast si potrebbe dire
lo stesso, per il codice volutamente criptico, per le notazioni tipo
1[array], ecc.
Tornando alla mia affermazione originaria, ribadisco che, a mio avviso,
l'uso che se ne dovrebbe fare è: quando le alternative sono più complesse.
Posso aggiungere che a me finora non è mai capitata una situazione in cui mi
sono sentito in dovere di usarlo, ma penso che sia poco influente...
--
Alessandro Monti

e' indubbio che generalmente [..]
Si, pero' quando sento le crociate sul GoTo mi viene il nervoso.
"Se adotti la tecnica A invece di B il codice sara' sempre piu'
leggibile e sara' ugualmente performate."
Io dico solo che con B il codice puo' essere ugualmente leggibile e
mantenibile. Saranno casi isolati, ma l'oltranzismo sul GoTo mi
ricorda l'oltranzismo della OOqualcosa. Io sono un procedurale
classico, e non mi sento superato, cosi come non mi interessa
minimamente se c'e' gente che mi guarda inorridita quando trova un
GoTo nel mio codice.
+++
Un novizio e' meglio che impari a non usare il GoTo nei suoi progammi,
pero' quando avra' una certa esperienza sarebbe meglio che
dimenticasse quel insegnamento, o per meglio dire, che ragionasse sui
perche' di quel insegnamento.
Il goto in se non rende il codice piu' illeggibile di una generica
cattiva programmazione. Si puo fare spaghetti code senza GoTo.


 cattiva programmazione. Si puo fare spaghetti code senza GoTo.
Ah, beh! In un'altra lettera ho indicato altri metodi per fare codice poco
leggibile, ma spero che le intenzioni del programmatore siano sempre quelle
di fare del codice pulito.
Concluderei allo stesso modo in cui ero partito: cercare di evitare il goto
tranne quando sembra necessario.
Tra l'altro il teorema di eliminabilità del goto dice una cosa interessante:
"è sempre possibile eliminare il goto al prezzo dell'introduzione di un
certo numero di variabili booleane".
Quindi una buona regola potrebbe essere: se devo introdurre almeno X
variabili solo per eliminare un goto (e gli X test correlati), allora è
preferibile usare il goto. Con X variabile da un programmatore all'altro, ma
io starei per un X>=3.
--
Alessandro Monti