5

sto avendo problemi in Visual Studio 2003 con il seguente:problema passando un riferimento come parametro di nome a una funzione variadic

void foo(const char*& str, ...) { 
    va_list args; 
    va_start(args, str); 

    const char* foo; 
    while((foo = va_arg(args, const char*)) != NULL) { 
     printf("%s\n", foo); 
    } 
} 

Quando lo chiamo io:

const char* one = "one"; 
foo(one, "two", "three", NULL); 

ottengo:

violazione di accesso posizione lettura 0xcccccccc

sulla riga printf() - va_arg() ha restituito 0xcccccccc. Alla fine ho scoperto che è il primo parametro a essere un riferimento che lo spezza - se faccio un normale char * tutto va bene. Non sembra importare quale sia il tipo; essere un riferimento fa sì che fallisca in fase di runtime. Si tratta di un problema noto con VS2003 o esiste un modo in cui questo è un comportamento legale? Non succede in GCC; Non ho provato con Visual Studio più recenti per vedere se il comportamento scompare

risposta

2

VS2005 si blocca anche su di esso.

Il problema è che va_start utilizza l'indirizzo dell'argomento che gli viene assegnato e poiché str è un riferimento, il suo indirizzo è l'indirizzo della variabile "uno" definita nel chiamante, non l'indirizzo nello stack.

vedo alcun modo di ottenere l'indirizzo della pila variabile (l'argomento che in realtà contiene l'indirizzo di "uno" che viene passato), ma ci sono alcuni arounds di lavoro:

  • Invece di "const char * str &", utilizzare "const char * str" o "const char ** str"
  • Aggiungi l'argomento successivo anche la lista degli argomenti "fisso"

Questo codice illustra la seconda alternativa :

void foo(const char* &str, const char *arg1, ...) { 
    if (arg1) { 
     va_list args; 
     va_start(args, arg1); 
     printf ("%s\n", arg1); 
     const char* foo; 
     while((foo = va_arg(args, const char*)) != NULL) { 
      printf("%s\n", foo); 
     } 
    } 
} 
+0

Oh, questo è davvero ovvio in retrospettiva; Immagino che l'implementazione di 'va_start' da parte di glibc non dipenda dall'indirizzo dell'ultimo argomento con nome, capisce l'inizio del ... altro modo –

+1

Basta trovarlo su http://www.velocityreviews.com/forums/ t281115-va_start-and-references.html che utilizzando va_start su un riferimento non è consentito. Vedi anche http://stackoverflow.com/questions/222195/are-there-gotchas-using-varargs-with-reference-parameters. – Patrick

+0

... wow. Il mio google-fu non è forte, ho cercato per anni –