Storia della domanda
L'operatore return è comparso nel C per terminare esplicitamente l'esecuzione di una funzione e restituire un risultato al codice che l'ha chiamata. Nei linguaggi di programmazione più vecchi, non sempre era possibile restituire valori, e il meccanismo return ha permesso di indicare esplicitamente il risultato delle computazioni. Ciò ha aumentato l'espressività e la sicurezza dei programmi.
Problema
La principale difficoltà: terminare correttamente la funzione e, se necessario, restituire un valore che corrisponda a un certo tipo. Gli errori si verificano spesso a causa della restituzione di un valore di tipo errato, puntatori a variabili non esistenti o locali, oppure l'ignorare il valore restituito dalla parte chiamante.
Soluzione
Esempio di codice:
#include <stdio.h> struct Point { int x, y; }; struct Point make_point(int x, int y) { // restituiamo una struttura (copia) struct Point p = {x, y}; return p; } int* dangerous() { int num = 42; return # // rischioso: restituiamo l'indirizzo di una variabile locale! } void do_nothing() { return; // corretto per funzioni di tipo void } int main() { struct Point p = make_point(3, 4); printf("%d %d\n", p.x, p.y); int* ptr = dangerous(); // UB: ptr punta a una zona distrutta }
Caratteristiche chiave:
È possibile usare return in funzioni senza valore (void)?
Risposta: Sì, è possibile scrivere "return;" per funzioni void, ma non è possibile specificare un'espressione (return x;) per una funzione void.
Cosa succede quando si restituisce un array da una funzione?
Risposta: In C non è possibile restituire direttamente un array. È possibile restituire solo un puntatore (ad esempio, a un array statico), ma più spesso è meglio restituire un puntatore e la dimensione o utilizzare un array allocato dinamicamente.
int* make_arr() { static int arr[5] = {1,2,3,4,5}; return arr; // un array statico vive dopo l'uscita dalla funzione }
Perché è rischioso restituire un puntatore a una variabile locale?
Risposta: Dopo l'uscita dalla funzione, la memoria per la variabile locale viene liberata (area dello stack). Utilizzare un puntatore restituito porta a un comportamento indefinito.
Caso negativo
La funzione restituisce un puntatore a una variabile locale, il chiamante riceve "spazzatura", un comportamento imprevedibile e rari bug fluttuanti.
Pro:
Contro:
Caso positivo
Utilizzo di una struttura restituita (copiata per valore) o restituzione di un puntatore a memoria statica/dinamica:
Pro:
Contro: