c – 将引用作为命名参数传递给可变参数函数时出现问题

我在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);

我明白了:

Access violation reading location 0xcccccccc

在printf()行 – va_arg()返回0xcccccccc.我终于发现它的第一个参数是一个打破它的引用 – 如果我把它作为普通的char *一切都很好.这种类型似乎并不重要;作为引用会导致它在运行时失败.这是VS2003的已知问题,还是某种方式存在合法行为?它不会发生在海湾合作委员会;我还没有测试过更新的Visual Studios,看看这个行为是否会消失

最佳答案
VS2005也崩溃了.

问题是va_start使用给它的参数的地址,并且由于str是引用,它的地址是调用者中定义的“one”变量的地址,而不是堆栈上的地址.

我认为无法获取stack-variable的地址(实际包含正在传递的“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);
       }
    }
}

转载注明原文:c – 将引用作为命名参数传递给可变参数函数时出现问题 - 代码日志