Provided by: manpages-pl-dev_4.21.0-2_all bug

NAZWA

       stdarg, va_start, va_arg, va_end, va_copy - listy zmiennych argumentów

BIBLIOTEKA

       Standardowa biblioteka C (libc, -lc)

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 przez 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 pierwsze.

       Parametr last jest nazwą ostatniego argumentu przed zmienną listą argumentów, czyli ostatnim  argumentem,
       którego typ jest funkcji znany.

       Ponieważ adres tego parametru jest używany w makrze va_start(), nie powinien 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.
       Argument ap to ap z va_list() zainicjowany przez va_start(). Każde wywołanie va_arg() zmienia ap tak,  że
       następne  wywołanie  zwraca następny argument. Argument 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()  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()
       Makro  va_copy()  kopiuje  (poprzednio  zainicjowaną)  listę src  argumentów o zmiennej długości do dest.
       Zachowanie to jest takie samo, jakby va_start() zostało zaaplikowane do dest z tym samym argumentem last,
       po którym następowałaby ta sama liczba wywołań va_arg(), która była  użyta  do  tej  pory,  aby  osiągnąć
       bieżący stan zmiennej src.

       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  przeciwwskazań  do
       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ę  konieczne  przydzielenie
       pamięci przez va_start(), przechowanie tam argumentów, jak też wskazań, który argument 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 być 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 nieudostępniające va_copy() mają zamiast niej __va_copy, gdyż ta  nazwa  była  używana  w  szkicu
       standardu.

ATRYBUTY

       Informacje o pojęciach używanych w tym rozdziale można znaleźć w podręczniku attributes(7).
       ┌────────────────────────────────────────────────────────────┬────────────────────────┬─────────────────┐
       │ InterfejsAtrybutWartość         │
       ├────────────────────────────────────────────────────────────┼────────────────────────┼─────────────────┤
       │ va_start(), va_end(), va_copy()                            │ Bezpieczeństwo wątkowe │ MT-Safe         │
       ├────────────────────────────────────────────────────────────┼────────────────────────┼─────────────────┤
       │ va_arg()                                                   │ Bezpieczeństwo wątkowe │ MT-Safe race:ap │
       └────────────────────────────────────────────────────────────┴────────────────────────┴─────────────────┘

STANDARDY

       C99.

BŁĘDY

       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).

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, ...)   /* '...' is C syntax for a variadic function */

       {
           va_list ap;
           int d;
           char c;
           char *s;

           va_start(ap, fmt);
           while (*fmt)
               switch (*fmt++) {
               case 's':              /* string */
                   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 */
                   /* need a cast here since va_arg only
                      takes fully promoted types */
                   c = (char) va_arg(ap, int);
                   printf("char %c\n", c);
                   break;
               }
           va_end(ap);
       }

ZOBACZ TAKŻE

       vprintf(3), vscanf(3), vsyslog(3)

TŁUMACZENIE

       Autorami  polskiego  tłumaczenia  niniejszej  strony podręcznika są: Przemek Borys <pborys@dione.ids.pl>,
       Andrzej Krzysztofowicz <ankry@green.mf.pg.gda.pl>, Robert Luberda  <robert@debian.org>  i  Michał  Kułach
       <michal.kulach@gmail.com>

       Niniejsze  tłumaczenie  jest  wolną  dokumentacją.  Bliższe informacje o warunkach licencji można uzyskać
       zapoznając  się  z  GNU General Public License w wersji 3  lub  nowszej.   Nie   przyjmuje   się   ŻADNEJ
       ODPOWIEDZIALNOŚCI.

       Błędy  w  tłumaczeniu  strony  podręcznika  prosimy  zgłaszać  na  adres  listy  dyskusyjnej manpages-pl-
       list@lists.sourceforge.net.

Linux man-pages 6.03                            5 lutego 2023 r.                                       stdarg(3)