Goto nei linguaggi ad alto livello: cosa ne pensate

Cos'è goto per te?

  • Un qualcosa che deve morire con estremo dolore

    Voti: 1 14.3%
  • Un qualcosa che deve morire senza dolore

    Voti: 2 28.6%
  • Un qualcosa che qualcuno potrebbe usare, ma io non sono quel qualcuno

    Voti: 1 14.3%
  • Un qualcosa di utile per determinati contesti specifici

    Voti: 3 42.9%
  • Un qualcosa che dovrebbe essere usato regolarmente

    Voti: 0 0.0%
  • Ma tu usi ancora i cicli?!?

    Voti: 0 0.0%

  • Votatori totali
    7
Pubblicità

Giacomo Furlan

Utente Attivo
Messaggi
369
Reazioni
93
Punteggio
48
Sono curioso. Conosco la letteratura a riguardo e so perché esistono, tuttavia la maggior parte delle persone lo considerano semplicemente "uno sbaglio dell'esistenza del programmatore che l'ha mai inventato (o implementato) nei linguaggi ad alto livello".
 
Penso che la sua esistenza non vincoli al suo utilizzo forzato (e smodato). In taluni casi forse può servire, ma generalmente non serve. Chi lo utilizza perchè "il linguaggio lo mette a disposizione e quindi significa che si può usare" non lo considero... :D
In linguaggi ad alto livello l'ho visto utilizzare raramente, ed in quasi tutti i casi si trattava di loop innestati dai quali si doveva uscire.

Hanno anche qualche aspetto positivo comunque, ma al giorno d'oggi sarebbe inutili riportarli in quanto il loro peso sarebbe decisamente inferiore rispetto ai negativi.

Comunque trovo corretta l'esistenza del costrutto in sè, anche ad alto livello. Poi come si sarà capito dalle prime righe, penso che spetti al programmatore sapere cosa sta facendo (purtroppo non sempre è così). Come sempre, "il problema è localizzato tra la tastiera e la sedia".
 
In Assembly le istruzioni di salto sono fondamentali, ma siamo a basso livello;
serve e si usa negli script.
In un linguaggio ad alto livello non serve né goto né suoi "derivati" (break/continue con etichetta).
Potrebbero far eccezione solo sw di sistema (processi, driver) in cui si persegue la massima velocità di esecuzione.
 
Nei generatori di codice vengono ampiamente usati, ad esempio. Si applicano sempre delle regole di buon senso, ossia "vai solo avanti". Certo sono error-prone perché potresti non avere a disposizione variabili date per inizializzate nel flusso normale del codice. A volte può essere utile specie in macchine a stati finiti, dove c'è una logica di cleanup condivisa e ritorno del valore e rende per assurdo la lettura del codice più intuitiva.

P.S. che io sappia i vari if, while, for... vengono convertiti in salti in fase di compilazione, quindi non credo che ci sia una differenza in performance rispetto ai goto.
 
P.S. che io sappia i vari if, while, for... vengono convertiti in salti in fase di compilazione, quindi non credo che ci sia una differenza in performance rispetto ai goto.

Il codice generato deve essere espresso sottoforma di salti, infatti l'uso - smodato - di goto in asm porta allo "spaghetti code".
I vari if, switch (ma qui differisce nella logica), while, for sono composti da un'istruzione che altera i bit del registro EFLAGS (CMP, TEST ma anche ADD ed altre) e successivamente da un'istruzione di salto condizionato Jxx (JE, JC, JNE, JA,...). Di fatto il salto avviene sulla base del flag o dei flag esaminati. Il salto avviene verso un indirizzo... non importa che sia l'istruzione successiva o 10 istruzioni sotto, che sia dentro ad un if, un for o fuori dai for.

Codice di Microsoft:
C:
#include <stdio.h>

int main()
{
    int i, j;

    for ( i = 0; i < 10; i++ )
    {
        printf_s( "Outer loop executing. i = %d\n", i );
        for ( j = 0; j < 3; j++ )
        {
            printf_s( " Inner loop executing. j = %d\n", j );
            if ( i == 5 )
                goto stop;
        }
    }

    /* This message does not print: */
    printf_s( "Loop exited. i = %d\n", i );

    stop: printf_s( "Jumped to stop. i = %d\n", i );
}

Essendo un costrutto messo a disposizione da un linguaggio di alto livello è soggetto ad alcune regole, quel goto (in asm... molte meno).
Si distinguono con maggior difficoltà i goto compilati, rispetto all'alto livello:
Codice:
CPU Disasm
Address   Hex dump          Command                                  Comments
00401630  /$  55            PUSH EBP                                 ; test.00401630(guessed void)
00401631  |.  89E5          MOV EBP,ESP
00401633  |.  83E4 F0       AND ESP,FFFFFFF0                         ; DQWORD (16.-byte) stack alignment
00401636  |.  83EC 20       SUB ESP,20
00401639  |.  E8 F2010000   CALL 00401830
0040163E  |.  C74424 1C 000 MOV DWORD PTR SS:[LOCAL.1],0
00401646  |.  EB 4A         JMP SHORT 00401692
00401648  |>  8B4424 1C     /MOV EAX,DWORD PTR SS:[LOCAL.1]
0040164C  |.  894424 04     |MOV DWORD PTR SS:[LOCAL.7],EAX
00401650  |.  C70424 644040 |MOV DWORD PTR SS:[LOCAL.8],OFFSET 00404 ; ASCII "Outer loop executing. i = %d
"
00401657  |.  E8 30110000   |CALL <JMP.&msvcrt.printf_s>             ; Jump to msvcrt.printf_s
0040165C  |.  C74424 18 000 |MOV DWORD PTR SS:[LOCAL.2],0
00401664  |.  EB 20         |JMP SHORT 00401686
00401666  |>  8B4424 18     |/MOV EAX,DWORD PTR SS:[LOCAL.2]
0040166A  |.  894424 04     ||MOV DWORD PTR SS:[LOCAL.7],EAX
0040166E  |.  C70424 844040 ||MOV DWORD PTR SS:[LOCAL.8],OFFSET 0040 ; ASCII " Inner loop executing. j = %d
"
00401675  |.  E8 12110000   ||CALL <JMP.&msvcrt.printf_s>            ; Jump to msvcrt.printf_s
0040167A  |.  837C24 1C 05  ||CMP DWORD PTR SS:[LOCAL.1],5
0040167F  |.  74 2E         ||JE SHORT 004016AF
00401681  |.  834424 18 01  ||ADD DWORD PTR SS:[LOCAL.2],1
00401686  |>  837C24 18 02  ||CMP DWORD PTR SS:[LOCAL.2],2
0040168B  |.^ 7E D9         |\JLE SHORT 00401666
0040168D  |.  834424 1C 01  |ADD DWORD PTR SS:[LOCAL.1],1
00401692  |>  837C24 1C 09  |CMP DWORD PTR SS:[LOCAL.1],9
00401697  |.^ 7E AF         \JLE SHORT 00401648
00401699  |.  8B4424 1C     MOV EAX,DWORD PTR SS:[LOCAL.1]
0040169D  |.  894424 04     MOV DWORD PTR SS:[LOCAL.7],EAX
004016A1  |.  C70424 A34040 MOV DWORD PTR SS:[LOCAL.8],OFFSET 004040 ; ASCII "Loop exited. i = %d
"
004016A8  |.  E8 DF100000   CALL <JMP.&msvcrt.printf_s>              ; Jump to msvcrt.printf_s
004016AD  |.  EB 01         JMP SHORT 004016B0
004016AF  |>  90            NOP
004016B0  |>  8B4424 1C     MOV EAX,DWORD PTR SS:[LOCAL.1]
004016B4  |.  894424 04     MOV DWORD PTR SS:[LOCAL.7],EAX
004016B8  |.  C70424 B84040 MOV DWORD PTR SS:[LOCAL.8],OFFSET 004040 ; ASCII "Jumped to stop. i = %d
"
004016BF  |.  E8 C8100000   CALL <JMP.&msvcrt.printf_s>              ; Jump to msvcrt.printf_s
004016C4  |.  B8 00000000   MOV EAX,0
004016C9  |.  C9            LEAVE
004016CA  \.  C3            RETN

Il goto è l'istruzione all'indirizzo:

Codice:
0040167F  |.  74 2E         ||JE SHORT 004016AF

trovandosi in un if, questo salto avviene solo se la variabile locale che viene testata è uguale a 5 (l'istruzione sopra a quel JE, si occupa del confronto).

Se non ci fosse quell'if però verrebbe tradotta come un JMP diretto (il goto alla fine è questo, un salto ad un determinato indirizzo), ma ovviamente il codice uscirebbe subito.
 
Ultima modifica:
Beh, chi in C utilizza break e continue in pratica utilizza un goto più sofisticato :) infatti io il goto lo utilizzavo in VB6 proprio perché non c’era l’equivalente del continue.
È buona pratica non utilizzarlo perché causa codice contorto (spaghetti code). Io lo utilizzo solo quando il salto è breve (poche istruzioni). Del resto quando il corpo di una funzione diventa troppo il codice diventa illeggibile e inizio a spezzarlo e a quel punto evito pure i goto.
 
Questa domanda “filosofica” è simile ad altre del tipo
1) usate una funzione con più di un return
2) usate break e continue
3) meglio usare un ciclo for o in ciclo while
4) fate un test logico con variabili non booleane
5) gli angeli sono maschi o femmine
E via dicendo.
Se siete a scuola, seguite le direttive.
Per divertirvi, usate quello che volete.
Per lavoro usare SEMPRE il buon senso
 
Ma sì infatti, era solo per accendere un dibattito costruttivo e, magari, togliere qualche tabu :)

Sono perfettamente d'accordo che se di goto si parla, di salti brevi (ed in avanti) si tratta :)
 
Pubblicità
Pubblicità
Indietro
Top