+
+\subsection{Il passaggio di variabili e valori di ritorno nelle funzioni}
+\label{sec:proc_var_passing}
+
+Una delle caratteristiche standard del C è che le variabili vengono passate
+alle funzioni che si invocano in un programma attraverso un meccanismo che
+viene chiamato \textit{by value}, diverso ad esempio da quanto avviene con il
+Fortran, dove le variabili sono passate, come suol dirsi, \textit{by
+ reference}, o dal C++ dove la modalità del passaggio può essere controllata
+con l'operatore \cmd{\&}.
+
+Il passaggio di una variabile \textit{by value} significa che in realtà quello
+che viene passato alla funzione è una copia del valore attuale di quella
+variabile, copia che la funzione potrà modificare a piacere, senza che il
+valore originale nella funzione chiamante venga toccato. In questo modo non
+occorre preoccuparsi di eventuali effetti delle operazioni svolte nella
+funzione stessa sulla variabile passata come argomento.
+
+Questo però va inteso nella maniera corretta. Il passaggio \textit{by value}
+vale per qualunque variabile, puntatori compresi; quando però in una funzione
+si usano dei puntatori (ad esempio per scrivere in un buffer) in realtà si va
+a modificare la zona di memoria a cui essi puntano, per cui anche se i
+puntatori sono copie, i dati a cui essi puntano saranno sempre gli stessi, e
+le eventuali modifiche avranno effetto e saranno visibili anche nella funzione
+chiamante.
+
+Nella maggior parte delle funzioni di libreria e delle \textit{system call} i
+puntatori vengono usati per scambiare dati (attraverso i buffer o le strutture
+a cui fanno riferimento) e le variabili normali vengono usate per specificare
+argomenti; in genere le informazioni a riguardo dei risultati vengono passate
+alla funzione chiamante attraverso il valore di ritorno. È buona norma
+seguire questa pratica anche nella programmazione normale.
+
+\itindbeg{value~result~argument}
+
+Talvolta però è necessario che la funzione possa restituire indietro alla
+funzione chiamante un valore relativo ad uno dei suoi argomenti usato anche in
+ingresso. Per far questo si usa il cosiddetto \textit{value result argument},
+si passa cioè, invece di una normale variabile, un puntatore alla stessa. Gli
+esempi di questa modalità di passaggio sono moltissimi, ad esempio essa viene
+usata nelle funzioni che gestiscono i socket (in
+sez.~\ref{sec:TCP_functions}), in cui, per permettere al kernel di restituire
+informazioni sulle dimensioni delle strutture degli indirizzi utilizzate,
+viene usato proprio questo meccanismo.
+
+Occorre tenere ben presente questa differenza, perché le variabili passate in
+maniera ordinaria, che vengono inserite nello \textit{stack}, cessano di
+esistere al ritorno di una funzione, ed ogni loro eventuale modifica
+all'interno della stessa sparisce con la conclusione della stessa, per poter
+passare delle informazioni occorre quindi usare un puntatore che faccia
+riferimento ad un indirizzo accessibile alla funzione chiamante.
+
+\itindend{value~result~argument}
+
+Questo requisito di accessibilità è fondamentale, infatti dei possibili
+problemi che si possono avere con il passaggio dei dati è quello di restituire
+alla funzione chiamante dei dati che sono contenuti in una variabile
+automatica. Ovviamente quando la funzione ritorna la sezione dello
+\textit{stack} che conteneva la variabile automatica (si ricordi quanto detto
+in sez.~\ref{sec:proc_mem_alloc}) verrà liberata automaticamente e potrà
+essere riutilizzata all'invocazione di un'altra funzione, con le immaginabili
+conseguenze, quasi invariabilmente catastrofiche, di sovrapposizione e
+sovrascrittura dei dati.
+
+Per questo una delle regole fondamentali della programmazione in C è che
+all'uscita di una funzione non deve restare nessun riferimento alle sue
+variabili locali. Qualora sia necessario utilizzare delle variabili che devono
+essere viste anche dalla funzione chiamante queste devono essere allocate
+esplicitamente, o in maniera statica usando variabili globali o dichiarate
+come \direct{extern},\footnote{la direttiva \direct{extern} informa il
+ compilatore che la variabile che si è dichiarata in una funzione non è da
+ considerarsi locale, ma globale, e per questo allocata staticamente e
+ visibile da tutte le funzioni dello stesso programma.} o dinamicamente con
+una delle funzioni della famiglia \func{malloc}, passando opportunamente il
+relativo puntatore fra le funzioni.
+
+
+\subsection{Il passaggio di un numero variabile di argomenti}
+\label{sec:proc_variadic}
+
+\index{funzioni!\textit{variadic}|(}
+
+Come vedremo nei capitoli successivi, non sempre è possibile specificare un
+numero fisso di argomenti per una funzione. Lo standard ISO C prevede nella
+sua sintassi la possibilità di definire delle \textit{variadic function} che
+abbiano un numero variabile di argomenti, attraverso l'uso nella dichiarazione
+della funzione dello speciale costrutto ``\texttt{...}'', che viene chiamato
+\textit{ellipsis}.
+
+Lo standard però non provvede a livello di linguaggio alcun meccanismo con cui
+dette funzioni possono accedere ai loro argomenti. L'accesso viene pertanto
+realizzato a livello della libreria standard del C che fornisce gli strumenti
+adeguati. L'uso di una \textit{variadic function} prevede quindi tre punti:
+\begin{itemize*}
+\item \textsl{dichiarare} la funzione come \textit{variadic} usando un
+ prototipo che contenga una \textit{ellipsis};
+\item \textsl{definire} la funzione come \textit{variadic} usando la stessa
+ \textit{ellipsis}, ed utilizzare le apposite macro che consentono la
+ gestione di un numero variabile di argomenti;
+\item \textsl{invocare} la funzione specificando prima gli argomenti fissi, ed
+ a seguire quelli addizionali.
+\end{itemize*}
+
+Lo standard ISO C prevede che una \textit{variadic function} abbia sempre
+almeno un argomento fisso. Prima di effettuare la dichiarazione deve essere
+incluso l'apposito \textit{header file} \headfile{stdarg.h}; un esempio di
+dichiarazione è il prototipo della funzione \func{execl} che vedremo in
+sez.~\ref{sec:proc_exec}:
+\includecodesnip{listati/exec_sample.c}
+in questo caso la funzione prende due argomenti fissi ed un numero variabile
+di altri argomenti, che andranno a costituire gli elementi successivi al primo
+del vettore \param{argv} passato al nuovo processo. Lo standard ISO C richiede
+inoltre che l'ultimo degli argomenti fissi sia di tipo
+\textit{self-promoting}\footnote{il linguaggio C prevede che quando si
+ mescolano vari tipi di dati, alcuni di essi possano essere \textsl{promossi}
+ per compatibilità; ad esempio i tipi \ctyp{float} vengono convertiti
+ automaticamente a \ctyp{double} ed i \ctyp{char} e gli \ctyp{short} ad
+ \ctyp{int}. Un tipo \textit{self-promoting} è un tipo che verrebbe promosso
+ a sé stesso.} il che esclude vettori, puntatori a funzioni e interi di tipo
+\ctyp{char} o \ctyp{short} (con segno o meno). Una restrizione ulteriore di
+alcuni compilatori è di non dichiarare l'ultimo argomento fisso come variabile
+di tipo \direct{register}.\footnote{la direttiva \direct{register} del
+ compilatore chiede che la variabile dichiarata tale sia mantenuta, nei
+ limiti del possibile, all'interno di un registro del processore; questa
+ direttiva è originaria dell'epoca dai primi compilatori, quando stava al
+ programmatore scrivere codice ottimizzato, riservando esplicitamente alle
+ variabili più usate l'uso dei registri del processore, oggi questa direttiva
+ è in disuso pressoché completo dato che tutti i compilatori sono normalmente
+ in grado di valutare con maggior efficacia degli stessi programmatori quando
+ sia il caso di eseguire questa ottimizzazione.}
+
+Una volta dichiarata la funzione il secondo passo è accedere ai vari argomenti
+quando la si va a definire. Gli argomenti fissi infatti hanno un loro nome, ma
+quelli variabili vengono indicati in maniera generica dalla
+\textit{ellipsis}. L'unica modalità in cui essi possono essere recuperati è
+pertanto quella sequenziale, in cui vengono estratti dallo \textit{stack}
+secondo l'ordine in cui sono stati scritti nel prototipo della funzione.
+
+\macrobeg{va\_start}
+
+Per fare questo in \headfile{stdarg.h} sono definite delle macro specifiche,
+previste dallo standard ISO C89, che consentono di eseguire questa operazione.
+La prima di queste macro è \macro{va\_start}, che inizializza opportunamente
+una lista degli argomenti, la sua definizione è:
+
+{\centering
+\begin{funcbox}{
+\fhead{stdarg.h}
+\fdecl{void va\_start(va\_list ap, last)}
+\fdesc{Inizializza una lista degli argomenti di una funzione
+ \textit{variadic}.}
+}
+\end{funcbox}}
+
+La macro inizializza il puntatore alla lista di argomenti \param{ap} che deve
+essere una apposita variabile di tipo \type{va\_list}; il
+parametro \param{last} deve indicare il nome dell'ultimo degli argomenti fissi
+dichiarati nel prototipo della funzione \textit{variadic}.
+
+\macrobeg{va\_arg}
+
+La seconda macro di gestione delle liste di argomenti di una funzione
+\textit{variadic} è \macro{va\_arg}, che restituisce in successione un
+argomento della lista; la sua definizione è:
+
+{\centering
+\begin{funcbox}{
+\fhead{stdarg.h}
+\fdecl{type va\_arg(va\_list ap, type)}
+\fdesc{Restituisce il valore del successivo argomento opzionale.}
+}
+\end{funcbox}}
+
+La macro restituisce il valore di un argomento, modificando opportunamente la
+lista \param{ap} perché una chiamata successiva restituisca l'argomento
+seguente. La macro richiede che si specifichi il tipo dell'argomento che si
+andrà ad estrarre attraverso il parametro \param{type} che sarà anche il tipo
+del valore da essa restituito. Si ricordi che il tipo deve essere
+\textit{self-promoting}.
+
+In generale è perfettamente legittimo richiedere meno argomenti di quelli che
+potrebbero essere stati effettivamente forniti, per cui nella esecuzione delle
+\macro{va\_arg} ci si può fermare in qualunque momento ed i restanti argomenti
+saranno ignorati. Se invece si richiedono più argomenti di quelli
+effettivamente forniti si otterranno dei valori indefiniti. Si avranno
+risultati indefiniti anche quando si chiama \macro{va\_arg} specificando un
+tipo che non corrisponde a quello usato per il corrispondente argomento.
+
+\macrobeg{va\_end}
+
+Infine una volta completata l'estrazione occorre indicare che si sono concluse
+le operazioni con la macro \macrod{va\_end}, la cui definizione è:
+
+{\centering
+\begin{funcbox}{
+\fhead{stdarg.h}
+\fdecl{void va\_end(va\_list ap)}
+\fdesc{Conclude l'estrazione degli argomenti di una funzione
+ \textit{variadic}.}
+}
+\end{funcbox}}
+
+Dopo l'uso di \macro{va\_end} la variabile \param{ap} diventa indefinita e
+successive chiamate a \macro{va\_arg} non funzioneranno. Nel caso del
+\cmd{gcc} l'uso di \macro{va\_end} può risultare inutile, ma è comunque
+necessario usarla per chiarezza del codice, per compatibilità con diverse
+implementazioni e per eventuali modifiche future a questo comportamento.
+
+Riassumendo la procedura da seguire per effettuare l'estrazione degli
+argomenti di una funzione \textit{variadic} è la seguente:
+\begin{enumerate*}
+\item inizializzare una lista degli argomenti attraverso la macro
+ \macro{va\_start};
+\item accedere agli argomenti con chiamate successive alla macro
+ \macro{va\_arg}: la prima chiamata restituirà il primo argomento, la seconda
+ il secondo e così via;
+\item dichiarare la conclusione dell'estrazione degli argomenti invocando la
+ macro \macro{va\_end}.
+\end{enumerate*}
+
+Si tenga presente che si possono usare anche più liste degli argomenti,
+ciascuna di esse andrà inizializzata con \macro{va\_start} e letta con
+\macro{va\_arg}, e ciascuna potrà essere usata per scandire la lista degli
+argomenti in modo indipendente. Infine ciascuna scansione dovrà essere
+terminata con \macro{va\_end}.
+
+Un limite di queste macro è che i passi 1) e 3) devono essere eseguiti nel
+corpo principale della funzione, il passo 2) invece può essere eseguito anche
+in un'altra funzione, passandole lista degli argomenti \param{ap}. In questo
+caso però al ritorno della funzione \macro{va\_arg} non può più essere usata
+(anche se non si era completata l'estrazione) dato che il valore di \param{ap}
+risulterebbe indefinito.
+
+\macroend{va\_start}
+\macroend{va\_arg}
+\macroend{va\_end}
+
+Esistono dei casi in cui è necessario eseguire più volte la scansione degli
+argomenti e poter memorizzare una posizione durante la stessa. In questo caso
+sembrerebbe naturale copiarsi la lista degli argomenti \param{ap} con una
+semplice assegnazione ad un'altra variabile dello stesso tipo. Dato che una
+delle realizzazioni più comuni di \type{va\_list} è quella di un puntatore
+nello \textit{stack} all'indirizzo dove sono stati salvati gli argomenti, è
+assolutamente normale pensare di poter effettuare questa operazione.
+
+\index{tipo!opaco|(}
+
+In generale però possono esistere anche realizzazioni diverse, ed è per questo
+motivo che invece che un semplice puntatore, \typed{va\_list} è quello che
+viene chiamato un \textsl{tipo opaco}. Si chiamano così quei tipi di dati, in
+genere usati da una libreria, la cui struttura interna non deve essere vista
+dal programma chiamante (da cui deriva il nome opaco) che li devono utilizzare
+solo attraverso dalle opportune funzioni di gestione.
+
+\index{tipo!opaco|)}
+
+Per questo motivo una variabile di tipo \typed{va\_list} non può essere
+assegnata direttamente ad un'altra variabile dello stesso tipo, ma lo standard
+ISO C99\footnote{alcuni sistemi che non hanno questa macro provvedono al suo
+ posto \macrod{\_\_va\_copy} che era il nome proposto in una bozza dello
+ standard.} ha previsto una macro ulteriore che permette di eseguire la
+copia di una lista degli argomenti:
+
+{\centering
+\begin{funcbox}{
+\fhead{stdarg.h}
+\fdecl{void va\_copy(va\_list dest, va\_list src)}
+\fdesc{Copia la lista degli argomenti di una funzione \textit{variadic}.}
+}
+\end{funcbox}}
+
+La macro copia l'attuale della lista degli argomenti \param{src} su una nuova
+lista \param{dest}. Anche in questo caso è buona norma chiudere ogni
+esecuzione di una \macrod{va\_copy} con una corrispondente \macro{va\_end} sul
+nuovo puntatore alla lista degli argomenti.
+
+La chiamata di una funzione con un numero variabile di argomenti, posto che la
+si sia dichiarata e definita come tale, non prevede nulla di particolare;
+l'invocazione è identica alle altre, con gli argomenti, sia quelli fissi che
+quelli opzionali, separati da virgole. Quello che però è necessario tenere
+presente è come verranno convertiti gli argomenti variabili.
+
+In Linux gli argomenti dello stesso tipo sono passati allo stesso modo, sia
+che siano fissi sia che siano opzionali (alcuni sistemi trattano diversamente
+gli opzionali), ma dato che il prototipo non può specificare il tipo degli
+argomenti opzionali, questi verranno sempre promossi, pertanto nella ricezione
+dei medesimi occorrerà tenerne conto (ad esempio un \ctyp{char} verrà visto da
+\macro{va\_arg} come \ctyp{int}).
+
+Un altro dei problemi che si devono affrontare con le funzioni con un numero
+variabile di argomenti è che non esiste un modo generico che permetta di
+stabilire quanti sono gli argomenti effettivamente passati in una chiamata.
+
+Esistono varie modalità per affrontare questo problema; una delle più
+immediate è quella di specificare il numero degli argomenti opzionali come uno
+degli argomenti fissi. Una variazione di questo metodo è l'uso di un argomento
+fisso per specificare anche il tipo degli argomenti variabili, come fa la
+stringa di formato per \func{printf} (vedi sez.~\ref{sec:file_formatted_io}).
+
+Infine una ulteriore modalità diversa, che può essere applicata solo quando il
+tipo degli argomenti lo rende possibile, è quella che prevede di usare un
+valore speciale per l'ultimo argomento, come fa ad esempio \func{execl} che
+usa un puntatore \val{NULL} per indicare la fine della lista degli argomenti
+(vedi sez.~\ref{sec:proc_exec}).
+
+\index{funzioni!\textit{variadic}|)}
+
+\subsection{Il controllo di flusso non locale}
+\label{sec:proc_longjmp}
+
+Il controllo del flusso di un programma in genere viene effettuato con le
+varie istruzioni del linguaggio C; fra queste la più bistrattata è il
+\instruction{goto}, che viene deprecato in favore dei costrutti della
+programmazione strutturata, che rendono il codice più leggibile e
+mantenibile. Esiste però un caso in cui l'uso di questa istruzione porta
+all'implementazione più efficiente e più chiara anche dal punto di vista della
+struttura del programma: quello dell'uscita in caso di errore.
+
+\index{salto~non-locale|(}
+
+Il C però non consente di effettuare un salto ad una etichetta definita in
+un'altra funzione, per cui se l'errore avviene in una funzione, e la sua
+gestione ordinaria è in un'altra, occorre usare quello che viene chiamato un
+\textsl{salto non-locale}. Il caso classico in cui si ha questa necessità,
+citato sia in \cite{APUE} che in \cite{GlibcMan}, è quello di un programma nel
+cui corpo principale vengono letti dei dati in ingresso sui quali viene
+eseguita, tramite una serie di funzioni di analisi, una scansione dei
+contenuti, da cui si ottengono le indicazioni per l'esecuzione di opportune
+operazioni.
+
+Dato che l'analisi può risultare molto complessa, ed opportunamente suddivisa
+in fasi diverse, la rilevazione di un errore nei dati in ingresso può accadere
+all'interno di funzioni profondamente annidate l'una nell'altra. In questo
+caso si dovrebbe gestire, per ciascuna fase, tutta la casistica del passaggio
+all'indietro di tutti gli errori rilevabili dalle funzioni usate nelle fasi
+successive. Questo comporterebbe una notevole complessità, mentre sarebbe
+molto più comodo poter tornare direttamente al ciclo di lettura principale,
+scartando l'input come errato.\footnote{a meno che, come precisa
+ \cite{GlibcMan}, alla chiusura di ciascuna fase non siano associate
+ operazioni di pulizia specifiche (come deallocazioni, chiusure di file,
+ ecc.), che non potrebbero essere eseguite con un salto non-locale.}
+
+Tutto ciò può essere realizzato proprio con un salto non-locale; questo di
+norma viene realizzato salvando il contesto dello \textit{stack} nel punto in
+cui si vuole tornare in caso di errore, e ripristinandolo, in modo da tornare
+quando serve nella funzione da cui si era partiti. La funzione che permette
+di salvare il contesto dello \textit{stack} è \funcd{setjmp}, il cui prototipo
+è:
+
+\begin{funcproto}{
+\fhead{setjmp.h}
+\fdecl{int setjmp(jmp\_buf env)}
+\fdesc{Salva il contesto dello \textit{stack}.}
+}
+{La funzione ritorna $0$ quando è chiamata direttamente ed un valore diverso
+ da zero quando ritorna da una chiamata di \func{longjmp} che usa il contesto
+ salvato in precedenza.}
+\end{funcproto}
+
+Quando si esegue la funzione il contesto corrente dello \textit{stack} viene
+salvato nell'argomento \param{env}, una variabile di tipo
+\typed{jmp\_buf}\footnote{anche questo è un classico esempio di variabile di
+ \textsl{tipo opaco}.} che deve essere stata definita in precedenza. In
+genere le variabili di tipo \type{jmp\_buf} vengono definite come variabili
+globali in modo da poter essere viste in tutte le funzioni del programma.
+
+Quando viene eseguita direttamente la funzione ritorna sempre zero, un valore
+diverso da zero viene restituito solo quando il ritorno è dovuto ad una
+chiamata di \func{longjmp} in un'altra parte del programma che ripristina lo
+\textit{stack} effettuando il salto non-locale. Si tenga conto che il contesto
+salvato in \param{env} viene invalidato se la funzione che ha chiamato
+\func{setjmp} ritorna, nel qual caso un successivo uso di \func{longjmp} può
+comportare conseguenze imprevedibili (e di norma fatali) per il processo.