Provided by: manpages-pl-dev_20060617-1_all bug

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

       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
                      va_list aq = ap;
       Niestety, są również systemy, które robią to poprzez tablicę wskaźników
       (o długości 1) i wtedy niezbędne jest
                      va_list aq;
                      *aq = *ap;
       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).

                                  2001-10-14                         STDARG(3)