NAZWA¶
stdarg - listy zmiennych argumentów
SKŁADNIA¶
#include <stdarg.h>
 
void va_start(va_list ap, last);
 
type va_arg(va_list ap, type);
 
void va_end(va_list ap);
 
void va_copy(va_list dest, va_list src);
OPIS¶
 Uwaga! To tłumaczenie może być nieaktualne!
Funkcję można wołać z różną liczbą
  argumentów, różnych typów. Plik nagłówkowy
  
stdarg.h deklaruje typ 
va_list i definiuje trzy makra,
  iterujące poprzez listę argumentów, których liczba i typy
  nie są znane wywołanej funkcji.
Wywołana funkcja musi zadeklarować obiekt typu 
va_list,
  który jest używany przez makra 
va_start, 
va_arg i
  
va_end.
va_start¶
Makro 
va_start inicjuje 
ap do dalszego użytku przez
  
va_arg i 
va_end, i musi być wywołane jako pierwsze.
Parametr 
last jest nazwą ostatniego parametru przed zmienną
  listą argumentów, czyli ostatnim parametrem, którego typ
  był funkcji znany.
Ponieważ adres tego parametru jest używany w makrze 
va_start,
  nie powinien on być deklarowany jako zmienna rejestrowa, funkcja czy typ
  tablicowy.
va_arg¶
Makro 
va_arg rozwija się do wyrażenia, które ma typ i
  wartość następnego argumentu w wywołaniu. Parametr
  
ap to 
va_list ap zainicjowany przez 
va_start.
  Każde wywołanie 
va_arg zmienia 
ap tak, że
  następne wywołanie zwraca następny argument. Parametr
  
type Jest nazwą typu, podaną tak że typ wskaźnika
  do obiektu, który ma podany typ można uzyskać przez dodanie *
  do 
type.
Pierwsze użycie makra 
va_arg po 
va_start zwraca argument za
  
last(ostatnim). Kolejne wywołania zwracają wartości
  pozostałych argumentów.
Jeśli nie ma następnego argumentu lub jeśli 
type nie jest
  zgodny z rzeczywistym typem następnego argumentu, pojawią się
  losowe błędy.
Jeśli 
ap zostanie przekazane do funkcji używającej
  
va_arg(ap,type), to
  wartość ap po zakończeniu tej funkcji będzie
  nieokreślona.
va_end¶
Każdemu wywołaniu 
va_start musi odpowiadać wywołanie
  
va_end w obrębie tej samej funkcji. Po wywołaniu
  
va_end(ap) wartość 
ap będzie
  nieokreślona. Lista może być przetwarzana wielokrotnie, przy
  czym każde przetworzenie musi być zawarte pomiędzy
  
va_start a 
va_end. 
va_end może być zarówno
  makrem, jak i funkcją.
va_copy¶
Oczywista implementacja zawierałaby wskaźnik 
va_list do ramki
  stosu funkcji o zmiennej liczbie argumentów. Przy takiej konfiguracji
  (jak dotąd, najpowszechniejszej) nie ma żadnych przeciwskazań
  wobec podstawienia
Niestety, są również systemy, które robią to poprzez
  tablicę wskaźników (o długości 1) i wtedy
  niezbędne jest
Wreszcie, w systemach, które przekazują parametry w rejestrach,
  może okazać się koniecznym przydzielenie pamięci przez
  
va_start, przechowanie tam parametrów, jak też wskazań,
  który parametr jest następny, tak aby 
va_arg mogło
  przejść całą listę. Wówczas 
va_end
  może wreszcie zwolnić przydzieloną w tym celu pamięć.
  Aby dostosować się do tej sytuacji, C99 dodaje makro 
va_copy,
  tak aby powyższe przypisanie mogło byc zastąpione przez
        va_list aq;
        va_copy(aq, ap);
        ...
        va_end(aq);
 
Każdemu wywołaniu 
va_copy musi odpowiadać wywołanie
  
va_end w obrębie tej samej funkcji. Niektóre systemy nie
  udostępniające 
va_copy posiadają zamiast tego
  
__va_copy, gdyż ta nazwa była używana w szkicowej
  propozycji standardu.
PRZYKŁADY¶
Funkcja 
foo pobiera łańcuch znaków formatujących i
  wypisuje argumenty z nimi związane w oparciu o typ argumentu.
#include <stdio.h>
#include <stdarg.h>
void foo(char *fmt, ...) {
	va_list ap;
	int d;
	char c, *p, *s;
	va_start(ap, fmt);
	while (*fmt)
		switch(*fmt++) {
		case 's':			/* napis */
			s = va_arg(ap, char *);
			printf("string %s\n", s);
			break;
		case 'd':			/* int */
			d = va_arg(ap, int);
			printf("int %d\n", d);
			break;
		case 'c':			/* char */
                        /* występuje tu potrzeba rzutowania, gdyż va_arg
                           pobiera w pełni awansowane typy */
			c = (char) va_arg(ap, int);
			printf("char %c\n", c);
			break;
		}
	va_end(ap);
}
 
ZGODNE Z¶
Makra 
va_start, 
va_arg, i 
va_end są zgodne z ANSI
  X3.159-1989 (``C89''). C99 definiuje makro 
va_copy.
KOMPATYBILNOŚĆ¶
Makra te 
nie są zgodne z historycznymi makrami, które
  zastąpiły. Zgodna wstecznie wersja znajduje się w pliku
  nagłówkowym 
varargs.h.
PORÓWNANIE¶
Historyczna konfiguracja to:
#include <varargs.h>
void foo(va_alist) va_dcl {
        va_list ap;
        va_start(ap);
        while(...) {
                ...
                x = va_arg(ap, type);
                ...
        }
        va_end(ap);
}
 
W niektórych systemach, 
va_end zawiera zamykający '}'
  odpowiadający '{' w 
va_start, tak żeby obydwa makra
  musiały wystąpić w tej samej funkcji w dozwolony sposób.
USTERKI¶
W przeciwieństwie do makr 
varargs, makra 
stdarg nie
  zezwalają programistom na tworzenie funkcji bez ustalonych
  argumentów. Problem ten powoduje utrudnienia podczas konwersji kodu
  
varargs na kod 
stdarg, a także utrudnia tworzenie funkcji,
  które mają za zadanie jedynie przekazać wszystkie swoje
  argumenty do funkcji pobierającej argument 
va_list, takiej jak
  
vfprintf(3).
Powyższe tłumaczenie pochodzi z nieistniejącego już Projektu
  Tłumaczenia Manuali i 
może nie być aktualne. W razie
  zauważenia różnic między powyższym opisem a
  rzeczywistym zachowaniem opisywanego programu lub funkcji, prosimy o
  zapoznanie się z oryginalną (angielską) wersją strony
  podręcznika za pomocą polecenia:
  
  - man --locale=C 3 stdarg
 
Prosimy o pomoc w aktualizacji stron man - więcej informacji można
  znaleźć pod adresem
  
http://sourceforge.net/projects/manpages-pl/.