[VC++] Functii cu numar variabil de parametri

Mediul de dezvoltare Visual C++, instalare, setari, debugger, compilator, linker si documentatie (forum moderat)
Post Reply
Viorel
Microsoft MVP
Microsoft MVP
Posts: 291
Joined: 13 Jul 2007, 12:26

[VC++] Functii cu numar variabil de parametri

Post by Viorel » 29 Dec 2008, 16:23

Funcţii cu număr variabil de parametri precedaţi de o referinţă.

O funcţie cu număr variabil de parametri include declaraţia „...” în lista parametrilor. Un exemplu îl constituie bine-cunoscuta funcţie printf disponibilă încă de la începuturile limbajului C:

Code: Select all

void printf(const char * format, ...);
Să examinăm situaţia în care am implementa o funcţie similară şi în care primul parametru ar fi o referinţă spre un string STL:

Code: Select all

void MyPrintf(const string & format, ...);
O astfel de funcţie este dificil de realizat din următoarele motive. Implementarea tipică a funcţiilor cu număr variabil de parametri presupune următoarea schemă [http://msdn.microsoft.com/en-us/library ... S.71).aspx]:

Code: Select all

void MyPrintf(const string & format, ...)
{
    va_list argptr;
    va_start(argptr, format);

    // (Detalii de implementare; se utilizează macro-ul va_arg)

    va_end( marker );         
}
Macro-urile va_list şi va_start definesc un pointer (argptr) şi îl iniţializează cu adresa parametrului care precede lista variabilă, deci cu adresa parametrului format. Codul expandat este:

Code: Select all

char * argptr; // va_list
argptr = (char*)&format; // va_start
Scopul macro-ului va_start şi a expresiei corespunzătoare argptr = (char*)&forma este obţinerea adresei locaţiei de pe stivă care să permită parcurgerea ulterioară a parametrilor variabili. Acest pas funcţionează corect în cazul funcţiei printf menţionate mai sus, deoarece &format semnifică adresa cuvîntului alocat pe stivă pentru parametrul format. Şi în cazul funcţiei MyPrintf ştiva va include un cuvînt conţinînd un pointer, drept că tratat ca referinţă. Însă, în cazul referinţelor, operatorul “&” semnifică altceva: este adresa argumentului real transferat spre funcţie. Deci în cazul unui apel:

Code: Select all

string s = "un text";
MyPrintf(s, 1, 2, 3);
expresia argptr = (char*)&format ar oferi de fapt adresa variabilei s, dar nu a locaţiei alocate pe stivă pentru argumentul s. Astfel nu mai este posibil accesul celorlalţi parametri ai funcţiei.

Prin urmare realizarea funcţiilor cu parametri de tip „(T &, ...)” este dificilă.


Next FAQ >>



Post Reply