我试图弄清楚 va_start(), va_arg() 宏的背后是什么。下面的代码运行良好。
#include <iostream>
#include <cstdarg>
void f(double a, double b, ...)
{
va_list arg;
va_start(arg, b);
double d;
while((d = va_arg(arg, double)) != 0)
{
std::cout << d << '\n';
}
}
int main(int argc, char *argv[])
{
f(1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 0.0);
return 0;
}
正如我所料,它给出了这样的输出:3 4 5 6 7 8 9。然后我找到了那个宏的定义(在互联网上,因为我的头文件 stdarg.h 很神秘——它定义了宏 va_arg(v, l) 像 _builtin_va_arg( v,l),最后一个没有在其中定义,stdarg.h 不包含任何内容,所以它在某个库中???)。然而,代替“cstdarg”,我写道:
typedef char* va_list;
#define _INTSIZEOF(n) \
((sizeof(n)+sizeof(int)-1) &~(sizeof(int)-1))
#define va_start(ap,v) \
(ap = (va_list)&v + _INTSIZEOF(v))
#define va_arg(ap,t) \
(*(t*)((ap += _INTSIZEOF(t)) - _INTSIZEOF(t)))
#define va_end(ap) (ap = (va_list)0)
输出变得很奇怪,例如 1 -0.0409377 -0.0409377 4.88084e-270 4.85706e-270 1 2 3 4 5 6 7 8 9。我认为可变参数放在最后声明的参数旁边,但显然还有更复杂的情况。如果有人揭露我错在哪里或那里真正发生了什么,我会非常高兴。