C++ 将引用作为命名参数传递给变量函数时出现问题
我在Visual Studio 2003中遇到以下问题:C++ 将引用作为命名参数传递给变量函数时出现问题,c++,visual-studio,reference,visual-studio-2003,variadic-functions,C++,Visual Studio,Reference,Visual Studio 2003,Variadic Functions,我在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 =
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);
我得到:
访问冲突读取位置0xCCCC
在
printf()
行--va_arg()
返回0xcccc。我最终发现它是第一个参数,是一个引用,它破坏了它——如果我把它变成一个普通的字符,一切都很好。什么类型似乎并不重要;作为引用会导致它在运行时失败。这是VS2003的一个已知问题,还是这是一种合法行为?它不会发生在GCC中;我还没有用较新的Visual Studio进行测试,看看这种行为是否消失了VS2005是否也会崩溃
问题是va_start使用给定给它的参数的地址,而且由于str是一个引用,它的地址是在调用者中定义的“one”变量的地址,而不是堆栈上的地址
我看不到获取堆栈变量地址的方法(实际包含正在传递的“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);
}
}
}
哦,回想起来,这是很明显的;我猜glibc的
va_start
的实现并不依赖于最后命名参数的地址,它计算出了。。。在引用上使用va_start是不允许的。另请参见。刚刚搜索了“va_arg参考C++”,等等。