5

estoy teniendo problemas en Visual Studio 2003 con lo siguiente:pasando una referencia como parámetro llamado a una función 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); 
    } 
} 

Cuando lo llamo:

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

me sale:

violación Access Localización lectura 0xcccccccc

en la línea printf() - va_arg() devolvió 0xcccccccc. Finalmente descubrí que es el primer parámetro que es una referencia que lo rompe, si lo hago un char * normal todo está bien. No parece importar qué tipo es; ser una referencia hace que falle en el tiempo de ejecución. ¿Es este un problema conocido con VS2003, o hay alguna forma en que ese es un comportamiento legal? No sucede en GCC; No he probado con estudios visuales más nuevos para ver si el comportamiento desaparece

Respuesta

2

VS2005 también se bloquea en él.

El problema es que va_start usa la dirección del argumento que se le da, y como str es una referencia, su dirección es la dirección de la variable "uno" definida en la persona que llama, no la dirección en la pila.

veo ninguna manera de conseguir la dirección de la pila variable (el argumento de que en realidad contiene la dirección de la que se pasa "uno"), pero hay algunos arounds de trabajo:

  • En lugar de "const char * str &", utilice "const char * str" o "const char ** str"
  • Añadir el siguiente argumento también a la lista de argumentos "fijo"

Este código ilustra la segunda 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, eso es realmente obvio en retrospectiva; Supongo que la implementación de glibc de 'va_start' no depende de la dirección del argumento final nombrado, se da cuenta del comienzo de ... de alguna otra manera –

+1

Acabo de encontrar en http://www.velocityreviews.com/forums/ t281115-va_start-and-references.html que no se permite usar va_start en una referencia. También vea http://stackoverflow.com/questions/222195/are-there-gotchas-using-varargs-with-reference-parameters. – Patrick

+0

... wow. Mi google-fu no es fuerte, busqué edades –

Cuestiones relacionadas