Проблема передачи ссылки в качестве именованного параметра в функцию с переменными параметрами - PullRequest
5 голосов
/ 18 мая 2010

У меня проблемы в Visual Studio 2003 со следующим:

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

Когда я это называю:

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

Я получаю:

Место чтения нарушения доступа 0xcccccccc

в строке printf() - va_arg() вернул 0xcccccccc. Наконец, я обнаружил, что это первый параметр, являющийся ссылкой, которая нарушает его - если я сделаю его обычным символом *, все в порядке Кажется, не имеет значения, что это за тип; ссылка является причиной сбоя во время выполнения. Это известная проблема с VS2003 или есть какое-то законное поведение? Это не происходит в GCC; Я не тестировал с более новыми Visual Studios, чтобы увидеть, исчезнет ли поведение

1 Ответ

2 голосов
/ 18 мая 2010

VS2005 также падает на нем.

Проблема в том, что va_start использует адрес данного ему аргумента, а поскольку str является ссылкой, его адрес является адресом переменной "one", определенной в вызывающей стороне, а не адресом в стеке. *

Я не вижу способа получить адрес переменной стека (аргумент, который фактически содержит адрес передаваемой единицы), но есть некоторые обходные пути:

  • Вместо «const char * & str» используйте «const char * str» или «const char ** str»
  • Добавить следующий аргумент также в список «фиксированных» аргументов

Этот код иллюстрирует второй вариант:

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