Newsgroup: it.comp.lang.c
Titolo: Puntatore a funzione

Salve,
avrei bisogno di un piccolo consulto per una questione che mi sfugge.
Schematizzo il listato del mio programma:
#include ...
double *funzione(...);
main()
{
 double *val,a,b;
 val=funzione(...);
 a=*val;
 b=*(val+1); 
 (etc.) 
}
double *funzione(...)
{
 double *ris,aa=...,bb=...;
 *ris=aa;
 *(ris+1)=bb;
 return(ris);
}
 
Il programma, cosi' come e' strutturato, funziona bene, 
ma in fase di compilazione ottengo il messaggio:
 
warning: function returns address of local variable
Poiche' immagino che sia indice di qualcosa di 'sporco',
vorrei capire perche' cio' accade e come risolverlo.
Grazie a chi mi rispondera'.
pau
p_...@exploit.it


ICQ #34602650

Marco Sarti ha ragione nella prima parte ma ha torto nella seconda:
|double *funzione()
|{
|  double aa;
|  /* altre operazioni */
|  return &aa;
|}
| ...... omissis
|La funzione che hai scritto invece è perfettamente lecita da questo
|punto di vista (non lo è sotto mille altri punti di vista :-)) per cui
|sospetto che non hai riportato fedelmente il codice che ha generato il
|warning.
Pau sta proprio facendo quello che mostri nell'esempio, ritornando fuori
dallo scope di funzione() il puntatore ris, che è locale e automatico (sta
sullo stack).
La versione corretta di funzione() è:
double *
funzione()
{
    static ris[2] = { valore_che_davi_ad_aa, valore_che_davi_a_bb } ;
    return (ris) ;
}
L'array dichiarato in area static ti fornisce la memoria che ti serve,
risolvendo il problema segnalato da Marco. La classe di allocazione static
inoltre assicura la permanenza del dato oltre il tempo di esecuzione di
funzione(), eliminando lo warning del compilatore e rendendo stabile il
programma.
Aldo

Scusate,
ovviamente mi sono sbagliato io e non Marco.
Effettivamente lo warning sembra ingiustificato con quel codice.
La mia versione corretta di funzione() è invece .... corretta.
Scuse soprattutto a Marco.
Ciao
Aldo

 Il programma, cosi' come e' strutturato, funziona bene,
Non credo proprio. E' cosě pieno di errori che non so da che parte
cominciare a correggerlo. Ti conviene provare da solo a riscriverlo
meglio e poi sottoporlo nuovamente a questo newsgroup. Intanto ti
consiglio di lasciar perdere il puntatore a double ed utilizzare
direttamente il tipo double (a meno che tu non abbia dei motivi
particolari, che non si evincono dall'esempio, per farlo).
EMG

 sullo stack).
Assolutamente falso. Una variabile locale (sia essa un puntatore, un
intero o un qualsivoglia tipo) può essere tranquillamente indicata come
ritorno della funzione. Ci mancherebbe altro...
Ciò che NON può essere ritornato è *l'indirizzo* di una variabile locale
e automatica. 


Salve e innanzitutto grazie a tutti per le risposte.
Riguardo al funzionamento del programma, ebbene fa davvero quello che
deve fare; sono cosciente che il tutto e' dovuto al caso, come afferma
anche Marco Sarti (a proposito, uso Linux), e per questo avevo bisogno
di una 'pulizia' che da solo non riesco a dare.
Il mio problema e' riuscire a far ritornare ad una funzione un array
di double, piuttosto che un solo double, senza cioe' utilizzare nel
programma globale delle ulteriori variabili esterne; inutile dire che
non sono riuscito a cavare null'altro che cio' che vi ho presentato (a
quanto pare orribile).
Comunque ho capito qual e' il problema segnalato dallo warning, ma non
ho ben capito come risolverlo in maniera 'pulita': ovvero, mi basta
dichiarare delle static?  e inoltre, come inizializzare correttamente
i vari puntatori a valore? E' sufficiente tutto cio' oppure bisogna
dare un'altra struttura al programma?
Vi ringrazio ancora e scusate l'ignoranza, ma da autodidatta sul C
soffro ancora di confusioni generate dalle mille (inutili) lezioni di
Pascal; so che dovrei leggere con ancora piu' attenzione la 'bibbia'
K&R, ma avevo un'urgenza particolare per il problema che vi ho posto.
Saluti,
pau
p_...@exploit.it

programma.
Secondo me non va risolto in questo modo il problema, ma semplicemente
allocando memoria per il valore puntato e assicurando (contrariamente
a "static") piena automaticita' al puntatore.

i vari puntatori a valore? 
Dichiarando nella funzione qualcosa del genere :
double * p = calloc ( 10, sizeof ( double ) ) ;
i valori p[0], p[1], p[2], ... vengono automaticamente azzerati.

 programma.
Stabile proprio non direi. Una soluzione del genere renderebbe la
funzione strettamente dipendente dalle chiamate effettuate ad essa.
Infatti il contenuto dell'array verrebbe probabilmente sovrascritto ad
ogni chiamata alterando indirettamente anche tutti i riferimenti
ricavati dalle chiamate precedenti.
EMG

 K&R,
Bene, vedi che ti sei risposto da solo? :-)
EMG

Grazie a tutti per l'aiuto.
Spero che con i vostri suggerimenti, soprattutto di Andrea, il mio
codice sia diventato anche robusto per futuri sviluppi.
Ciao.
pau
p_...@exploit.it

effettivamente utilizzati.
no, intendevo solo dire che, data la diversa gestione delle variabili
in Pascal, tendo ancora a confondere alcuni aspetti.
D'accordo sul fatto che come base ne ho sicuramente tratto solo
vantaggi.
Ciao.