Provided by: manpages-pl-dev_4.18.1-1_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
       ⟨https://www.gnu.org/licenses/gpl-3.0.html⟩   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⟩.