Che cos'è una chiamata di coda?

Nella programmazione del computer, una chiamata di coda è una situazione specifica all'interno del codice sorgente del programma in cui una funzione, una subroutine o una procedura restituisce un valore previsto chiamando un'altra funzione invece di passare semplicemente una variabile che contiene il valore restituito. Il nome stesso indica che la funzione chiamata per calcolare il valore da restituire si trova alla fine, o coda, della funzione che la chiama per fornire un valore di ritorno. Una chiamata di coda è interessante per alcuni programmatori perché, con alcune ottimizzazioni o comportamenti del compilatore, non viene utilizzato spazio di stack aggiuntivo per memorizzare le posizioni di codice della funzione principale; la funzione tail viene invece utilizzata per generare i report dei valori di ritorno direttamente al punto di chiamata in cui è stata invocata la funzione originale. L'uso di una chiamata di coda è particolarmente utile nelle situazioni in cui viene utilizzata la ricorsione, poiché la quantità di spazio di stack utilizzata per memorizzare gli indirizzi del chiamante nei casi in cui le chiamate ricorsive si annidano molto profondamente potrebbe esaurirsi rapidamente e arrestare l'esecuzione del programma. Sebbene l'utilizzo delle chiamate di coda possa aiutare ad aumentare la velocità, l'utilizzo della memoria e l'efficienza in un programma, può anche portare a situazioni in cui il codice sorgente è ristrutturato per utilizzare le chiamate in un modo che rende difficile il debug e il tracciamento, specialmente con casi di ricorsione.

L'esistenza di una chiamata di coda è dovuta in gran parte a come funziona lo stack di chiamate all'interno della maggior parte dei programmi per computer e architetture di sistema. Lo stack, che è come una pila di piatti, è una struttura dati first-in, last-out. Quando viene chiamata una funzione, una subroutine o una procedura, l'indirizzo da cui viene effettuata la chiamata, chiamato frame dello stack, viene memorizzato nello stack. Ciò significa che un programma che chiama la funzione A, che quindi chiama la funzione B, avrà due frame di stack, uno per la funzione B e un altro sotto di esso per la funzione A. Al termine dell'esecuzione della funzione B, il frame di stack viene visualizzato dalla parte superiore del stack ed esecuzione ritornano alla funzione A, che ha il suo frame saltato fuori dallo stack quando ha finito, restituendo infine il controllo del programma al punto da cui era originariamente chiamata la prima funzione.

Quando viene utilizzata una chiamata di coda, l'istruzione return in una funzione utilizza direttamente il valore restituito di un'altra funzione come dati da inviare al codice chiamante. Nell'esempio sopra, se la funzione A chiama la funzione B direttamente con l'istruzione return, allora è stata formata una chiamata di coda. All'interno dello stack di chiamate, anziché disporre di un frame di stack per entrambe le funzioni A e B, la funzione B riceverà l'indirizzo di ritorno dalla funzione A e il frame di stack della funzione A verrà visualizzato e eliminato, il che significa che la funzione B passerà il valore di ritorno direttamente indietro alla posizione che ha chiamato la funzione A senza prima dover passare il controllo alla funzione A. Ciò aumenta la velocità delle chiamate di funzione e aiuta a contenere la quantità di informazioni nello stack.

Le proprietà di una chiamata in coda possono renderle un'opzione molto interessante per le funzioni ricorsive. Una funzione ricorsiva è una funzione che si chiama ripetutamente per calcolare un valore, come può accadere quando si attraversa una struttura di dati di elenco. Non vengono creati frame di stack aggiuntivi per le chiamate di funzione nidificate, quindi livelli di ricorsione molto profondi possono essere eseguiti in sicurezza senza la minaccia immediata di un overflow dello stack e la possibile conclusione del programma.

ALTRE LINGUE

Questo articolo è stato utile? Grazie per il feedback Grazie per il feedback

Come possiamo aiutare? Come possiamo aiutare?