+\subsection{Il passaggio di un numero variabile di argomenti}
+\label{sec:proc_variadic}
+
+Come vedremo nei capitoli successivi, non sempre è possibile specificare un
+numero fisso di parametri 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 della
+\textit{ellipsis} \var{...} nella dichiarazione della funzione; ma non
+provvede a livello di linguaggio alcun meccanismo con cui dette funzioni
+possono accedere ai loro argomenti.
+
+L'accesso viene invece realizzato dalle librerie standard che provvedono gli
+strumenti adeguati. L'uso delle \textit{variadic function} prevede 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 lo stesso
+ \textit{ellipsis}, ed utilizzare le apposite macro che consentono la
+ gestione di un numero variabile di argomenti.
+\item \textsl{Chiamare} la funzione specificando prima gli argomenti fissi, e
+ a seguire gli 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 header file \file{stdarg.h}; un esempio di dichiarazione è
+il prototipo della funzione \func{execl} che vedremo in
+\secref{sec:proc_exec}:
+\begin{lstlisting}[labelstep=0,frame=,indent=1cm]{}
+ int execl(const char *path, const char *arg, ...);
+\end{lstlisting}
+in questo caso la funzione prende due parametri fissi ed un numero variabile
+di altri parametri (che verranno a costituire gli elementi successivi al primo
+del vettore \var{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 array, 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 parametro fisso come
+\ctyp{register}.
+
+Una volta dichiarata la funzione il secondo passo è accedere ai vari parametri
+quando la si va a definire. I parametri fissi infatti hanno un loro nome, ma
+quelli variabili vengono indicati in maniera generica dalla ellipsis.
+
+L'unica modalità in cui essi possono essere recuperati è pertanto quella
+sequenziale; essi verranno estratti dallo stack secondo l'ordine in cui sono
+stati scritti. Per fare questo in \file{stdarg.h} sono definite delle apposite
+macro; la procedura da seguire è la seguente:
+\begin{enumerate*}
+\item Inizializzare un puntatore alla lista degli argomenti di tipo
+ \type{va\_list} attraverso la macro \macro{va\_start}.
+\item Accedere ai vari argomenti opzionali 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 dei parametri invocando la
+ macro \macro{va\_end}.
+\end{enumerate*}
+in generale è perfettamente legittimo richiedere meno argomenti di quelli che
+potrebbero essere stati effettivamente forniti, e 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 forniti si
+otterranno dei valori indefiniti. Nel caso del \cmd{gcc} l'uso della macro
+\macro{va\_end} è inutile, ma si consiglia di usarlo ugualmente per
+compatibilità.
+
+Le definizioni delle tre macro sono le seguenti:
+\begin{functions}
+ \headdecl{stdarg.h}
+
+ \funcdecl{void va\_start(va\_list ap, last)} Inizializza il puntatore alla
+ lista di argomenti \param{ap}; il parametro \param{last} \emph{deve} essere
+ l'ultimo dei parametri fissi.
+
+ \funcdecl{type va\_arg(va\_list ap, type)} Restituisce il valore del
+ successivo parametro opzionale, modificando opportunamente \param{ap}; la
+ macro richiede che si specifichi il tipo dell'argomento attraverso il
+ parametro \param{type} che deve essere il nome del tipo dell'argomento in
+ questione. Il tipo deve essere \textit{self-promoting}.
+
+ \funcdecl{void va\_end(va\_list ap)} Conclude l'uso di \param{ap}.
+\end{functions}
+
+In generale si possono avere più puntatori alla lista degli argomenti,
+ciascuno andrà inizializzato con \macro{va\_start} e letto con \macro{va\_arg}
+e ciascuno potrà scandire la lista degli argomenti per conto suo.
+
+Dopo l'uso di \macro{va\_end} la variabile \var{ap} diventa indefinita e
+successive chiamate a \macro{va\_arg} non funzioneranno. Si avranno risultati
+indefiniti anche chiamando \macro{va\_arg} specificando un tipo che non
+corrisponde a quello del parametro.
+
+Un altro limite delle macro è che i passi 1) e 3) devono essere eseguiti nel
+corpo principale della funzione, il passo 2) invece può essere eseguito anche
+in una subroutine passandole il puntatore alla lista di argomenti; in questo
+caso però si richiede che al ritorno della funzione il puntatore non venga più
+usato (lo standard richiederebbe la chiamata esplicita di \macro{va\_end}),
+dato che il valore di \var{ap} risulterebbe indefinito.
+
+Esistono dei casi in cui è necessario eseguire più volte la scansione dei
+parametri e poter memorizzare una posizione durante la stessa. La cosa più
+naturale in questo caso sembrerebbe quella di copiarsi il puntatore alla lista
+degli argomenti con una semplice assegnazione. Dato che una delle
+realizzazioni più comuni di \macro{va\_list} è quella di un puntatore nello
+stack all'indirizzo dove sono stati salvati i parametri, è assolutamente
+normale pensare di poter effettuare questa operazione.
+
+In generale però possono esistere anche realizzazioni diverse, per questo
+motivo \macro{va\_list} è definito come \textsl{tipo opaco} e non può essere
+assegnato direttamente ad un'altra variabile dello stesso tipo. Per risolvere
+questo problema lo standard ISO C99\footnote{alcuni sistemi che non hanno
+ questa macro provvedono al suo posto \macro{\_\_va\_copy} che era il nome
+ proposto in una bozza dello standard.} ha previsto una macro ulteriore che
+permette di eseguire la copia di un puntatore alla lista degli argomenti:
+\begin{prototype}{stdarg.h}{void va\_copy(va\_list dest, va\_list src)}
+ Copia l'attuale valore \param{src} del puntatore alla lista degli argomenti
+ su \param{dest}.
+\end{prototype}
+\noindent anche in questo caso è buona norma chiudere ogni esecuzione di una
+\macro{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 i parametri, 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}).
+
+Uno 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 i parametri passati effettivamente 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 parametro
+per specificare anche il tipo degli argomenti (come fa la stringa di formato
+per \func{printf}).
+
+Una modalità diversa, che può essere applicata solo quando il tipo dei
+parametri lo rende possibile, è quella che prevede di usare un valore speciale
+come ultimo argomento (come fa ad esempio \func{execl} che usa un puntatore
+\macro{NULL} per indicare la fine della lista degli argomenti).
+
+