Provided by: manpages-pl-dev_4.23.1-1_all 

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). ┌───────────────────────────────────────────────────────┬────────────────────────┬───────────────────────┐ │Interfejs │ Atrybut │ Wartość │ ├───────────────────────────────────────────────────────┼────────────────────────┼───────────────────────┤ │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⟩.