可能重复:
Are there gotchas using varargs with reference parameters
嗨,我的varargs有问题。 查看我的代码(Microsoft Visual Studio 2005或2008)。
#include <stdarg.h>
struct Test { int a; };
void T1(int n, ...) {
va_list args;
va_start(args, n);
char* p = va_arg(args, char*);
va_end(args);
}
void T2(Test n, ...) {
va_list args;
va_start(args, n);
char* p = va_arg(args, char*);
va_end(args);
}
void T3(const Test& n, ...) {
va_list args;
va_start(args, n);
char* p = va_arg(args, char*); // p corrupt!!
va_end(args);
}
int _tmain(int argc, _TCHAR* argv[]) {
const Test t;
T1(1, "Test1");
T2(t, "Test2");
T3(t, "Test3");
return 0;
}
功能T1,T2运行良好。但T3功能有问题。指针p不指向“Test3”。我不能将va_start与pass-by-reference一起使用吗? 提前谢谢。
答案 0 :(得分:13)
根据C ++标准18.7 / 3,您不能使用va_start
的引用:
ISO C对标头中va_start()宏的第二个参数的限制 在这个国际标准中有所不同。参数parmN是。的标识符 函数定义的变量参数列表中最右边的参数(就在...之前的那个)。 如果参数parmN使用函数,数组或引用类型声明,或者使用不兼容的类型声明 使用在传递没有参数的参数时得到的类型,行为是 未定义。
答案 1 :(得分:4)
简短回答:不,你做不到。
注意:我看到第一个引用标准的答案,但我相信值得展示我的测试。
va_start
的定义如下:
视觉6:#define va_start(ap,v) ( ap = (va_list)&v + _INTSIZEOF(v) )
视觉8:#define _crt_va_start(ap,v) ( __va_start(&ap, _ADDRESSOF(v), _SLOTSIZEOF(v), \
__alignof(v), _ADDRESSOF(v)) )
使用此代码:
#include <cstdio>
int main()
{
char c;
char &rc = c;
int i;
int &ri = i;
printf("char ref:%d\n", sizeof(rc));
printf("int ref:%d\n", sizeof(ri));
return 0;
}
输出
char ref:1
int ref:4
由于在实现级别引用以与指针类似的方式在堆栈上传递,这表示一个问题,因为大小不同(这是因为宏计算了类型的大小而没有考虑参数实际上是引用,它不是常数,而是取决于类型的实际大小。)