stdarg(3) Library Functions Manual stdarg(3) NUME stdarg, va_start, va_arg, va_end, va_copy - liste de argumente variabile BIBLIOTECA Biblioteca C standard (libc, -lc) SINOPSIS #include 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); DESCRIERE O funcie poate fi apelata cu un numar variabil de argumente de diferite tipuri. Fiierul de includere declara un tip va_list i definete trei macro pentru parcurgerea unei liste de argumente al caror numar i tipuri nu sunt cunoscute de funcia apelata. Funcia apelata trebuie sa declare un obiect de tip va_list care este utilizat de macrocomenzile va_start(), va_arg() i va_end(). va_start() Macrocomanda va_start() iniializeaza ap pentru utilizarea ulterioara de catre va_arg() i va_end() i trebuie sa fie apelata prima. Argumentul last este numele ultimului argument inainte de lista de argumente a variabilei, adica ultimul argument al carui tip este cunoscut de catre funcia apelanta. Deoarece adresa acestui argument poate fi utilizata in macrocomanda va_start(), acesta nu trebuie sa fie declarat ca o variabila de registru sau ca o funcie sau un tip de matrice. va_arg() Macrocomanda va_arg() se extinde la o expresie care are tipul i valoarea urmatorului argument din apel. Argumentul ap este va_list ap iniializat de va_start(). Fiecare apel la va_arg() modifica ap astfel incat urmatorul apel returneaza urmatorul argument. Argumentul type este un nume de tip specificat astfel incat tipul unui indicator la un obiect care are tipul specificat sa poata fi obinut prin simpla adaugare a unui * la type. Prima utilizare a macrocomenzii va_arg() dupa cea a macrocomenzii va_start() returneaza argumentul dupa last. Invocarile succesive returneaza valorile celorlalte argumente. In cazul in care nu exista un argument urmator sau daca tip nu este compatibil cu tipul argumentului urmator real (promovat in conformitate cu promoiile de argumente implicite), vor aparea erori aleatorii. Daca ap este pasat unei funcii care utilizeaza va_arg(ap,tip), atunci valoarea lui ap este nedefinita dupa returnarea acelei funcii. va_end() Fiecare invocare a va_start() trebuie sa fie insoita de o invocare corespunzatoare a va_end() in cadrul aceleiai funcii. Dupa apelul va_end(ap), variabila ap este nedefinita. Sunt posibile mai multe parcurgeri ale listei, fiecare dintre ele intre paranteze de va_start() i va_end(). va_end() poate fi o macrocomanda sau o funcie. va_copy() Macrocomanda va_copy() copiaza lista de argumente variabile (iniializata anterior) src in dest. Comportamentul este ca i cum va_start() ar fi aplicat la dest cu acelai argument last, urmat de acelai numar de invocari va_arg() care a fost utilizat pentru a ajunge la starea actuala a src. O implementare evidenta ar fi ca va_list sa fie un indicator la cadrul de stiva al funciei cu numar de argumente variabile. Intr-o astfel de configuraie (de departe cea mai comuna) nu pare sa existe nimic impotriva unei atribuiri va_list aq = ap; Din nefericire, exista i sisteme care o transforma intr-o matrice de indicatori (de lungime 1), iar acolo este nevoie de va_list aq; *aq = *ap; In cele din urma, pe sistemele in care argumentele sunt transmise in registre, poate fi necesar ca va_start() sa aloce memorie, sa stocheze acolo argumentele, precum i o indicaie a argumentului care urmeaza, astfel incat va_arg() sa poata parcurge lista. Acum, va_end() poate elibera din nou memoria alocata. Pentru a se adapta la aceasta situaie, C99 adauga o macrocomanda va_copy(), astfel incat atribuirea de mai sus poate fi inlocuita cu va_list aq; va_copy(aq, ap); ... va_end(aq); Fiecare invocare a va_copy() trebuie sa fie insoita de o invocare corespunzatoare a va_end() in cadrul aceleiai funcii. Unele sisteme care nu furnizeaza va_copy() au in schimb __va_copy, deoarece acesta a fost numele utilizat in proiectul de propunere. ATRIBUTE Pentru o explicaie a termenilor folosii in aceasta seciune, a se vedea attributes(7). +------------------------------+---------------------+-----------------+ |Interfaa | Atribut | Valoare | +------------------------------+---------------------+-----------------+ |va_start(), va_end(), | Sigurana firelor | MT-Safe | |va_copy() | | | +------------------------------+---------------------+-----------------+ |va_arg() | Sigurana firelor | MT-Safe race:ap | +------------------------------+---------------------+-----------------+ STANDARDE C11, POSIX.1-2008. ISTORIC va_start() va_arg() va_end() C89, POSIX.1-2001. va_copy() C99, POSIX.1-2001. AVERTISMENTE Spre deosebire de macrocomenzile istorice varargs, macrocomenzile stdarg nu permit programatorilor sa codifice o funcie fara argumente fixe. Aceasta problema genereaza munca mai ales la convertirea codului varargs in cod stdarg, dar creeaza dificultai i pentru funciile cu numar de argumente variabile, ,,variadice", care doresc sa transmita toate argumentele lor unei funcii care ia un argument va_list, cum ar fi vfprintf(3). EXEMPLE Funcia foo preia un ir de caractere de format i afieaza argumentul asociat fiecarui caracter de format in funcie de tip. #include #include void foo(char *fmt, ...) /* '...' este sintaxa C pentru o funcie variadica */ { va_list ap; int d; char c; char *s; va_start(ap, fmt); while (*fmt) switch (*fmt++) { case 's': /* ir */ s = va_arg(ap, char *); printf("ir %s\n", s); break; case 'd': /* numar intreg */ d = va_arg(ap, int); printf("numar intreg %d\n", d); break; case 'c': /* caracter */ /* avem nevoie de o conversie de tip aici, deoarece va_arg accepta numai tipuri complet promovate */ c = (char) va_arg(ap, int); printf("caracter %c\n", c); break; } va_end(ap); } CONSULTAI I vprintf(3), vscanf(3), vsyslog(3) TRADUCERE Traducerea in limba romana a acestui manual a fost facuta de Remus- Gabriel Chelu Aceasta traducere este documentaie gratuita; citii Licena publica generala GNU Versiunea 3 sau o versiune ulterioara cu privire la condiii privind drepturile de autor. NU se asuma NICIO RESPONSABILITATE. Daca gasii erori in traducerea acestui manual, va rugam sa trimitei un e-mail la . Pagini de manual de Linux 6.8 2 mai 2024 stdarg(3)