plucky (3) stdarg.3.gz

Provided by: manpages-pl-dev_4.25.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-bezpieczne         │
       ├───────────────────────────────────────────────────────┼────────────────────────┼───────────────────────┤
       │va_arg()                                               │ Bezpieczeństwo wątkowe │ MT-bezpieczne race:ap │
       └───────────────────────────────────────────────────────┴────────────────────────┴───────────────────────┘

STANDARDY

       C11, POSIX.1-2008.

HISTORIA

       va_start()
       va_arg()
       va_end()
              C89, POSIX.1-2001.

       va_copy()
              C99, POSIX.1-2001.

ZASTRZEŻENIA

       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, ...)   /* '...' jest składnią języka C dla funkcji
                                 o zmiennej liczbie argumentów */

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

           va_start(ap, fmt);
           while (*fmt)
               switch (*fmt++) {
               case 's':              /* łańcuch */
                   s = va_arg(ap, char *);
                   printf("łańcuch %s\n", s);
                   break;
               case 'd':              /* liczba całkowita*/
                   d = va_arg(ap, int);
                   printf("liczba całkowita %d\n", d);
                   break;
               case 'c':              /* znak */
                   /* występuje tu potrzeba rzutowania, gdyż va_arg
                      pobiera w pełni awansowane typy */
                   c = (char) va_arg(ap, int);
                   printf("znak %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⟩.