5

Je vais avoir des problèmes dans Visual Studio 2003 avec les éléments suivants:problème passer une référence en tant que paramètre nommé à une fonction variadique

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); 
    } 
} 

Quand je l'appelle:

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

Je reçois:

violation d'accès emplacement de lecture 0xcccccccc

sur la ligne printf() - va_arg() a renvoyé 0xcccccccc. J'ai finalement découvert que le premier paramètre est une référence qui le casse - si j'en fais un caractère normal * tout va bien. Cela ne semble pas avoir d'importance quel est le type; être une référence provoque l'échec à l'exécution. Est-ce un problème connu avec VS2003 ou existe-t-il un comportement légal? Cela n'arrive pas dans GCC; Je n'ai pas testé avec Visual Studios plus récents pour voir si le comportement disparaît

Répondre

2

VS2005 se bloque également sur elle. Le problème est que va_start utilise l'adresse de l'argument qui lui est donné, et puisque str est une référence, son adresse est l'adresse de la variable "one" définie dans l'appelant, pas l'adresse sur la pile.

Je ne vois aucun moyen d'obtenir l'adresse de la pile variable (l'argument qui contient en fait l'adresse de « un » qui est passé), mais il y a des travaux contournements:

  • Au lieu de "const char * & str", utilisez "const char * str" ou "const char ** str"
  • Ajouter le prochain argument aussi à la "fixe" la liste des arguments

Ce code illustre la seconde alternative :

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, c'est vraiment évident en rétrospective; Je suppose que l'implémentation de 'va_start' de glibc ne dépend pas de l'adresse de l'argument final nommé, elle détermine le début de la ... d'une autre façon –

+1

Justement trouvé sur http://www.velocityreviews.com/forums/ t281115-va_start-and-references.html que l'utilisation de va_start sur une référence n'est pas autorisée. Voir aussi http://stackoverflow.com/questions/222195/are-there-gotchas-using-varargs-with-reference-parameters. – Patrick

+0

... wow. Mon google-fu n'est pas fort, j'ai cherché des années –

Questions connexes