五、 Unix System V兼容方式的va声明
上面介绍可变参数函数的声明是采用ANSI标准的,Unix System V兼容方式的声明有一点点区别,它增加了两个宏:va_alist,va_dcl。而且它们不是定义在stdarg.h中,而是varargs.h中。stdarg.h是ANSI标准的;varargs.h仅仅是为了能与以前的程序保持兼容而出现的,现在的编程中不推荐使用。
va_alist:函数声明/定义时出现在函数头,用以接受参数列表。
va_dcl:对va_alist的声明,其后无需跟分号";"
va_start的定义也不相同。因为System V可变参数函数声明不区分固定参数和可选参数,直接对参数列表操作。所以va_start()不是va_start(ap,v),而是简化为va_start(ap)。其中,ap是va_list型的参数指针。
Unix System V兼容方式下函数的声明形式:
type VAFunction(va_alist)
va_dcl // 这里无需分号
{
// 函数体内同ANSI标准
}
// 例3:猜测execl的实现(Unix System V兼容方式),摘自SUS V2
#include
#define MAXARGS 100
/ * execl(file, arg1, arg2, ..., (char *)0); */
execl(va_alist)
va_dcl
{
va_list ap;
char *file;
char *args[MAXARGS];
int argno = 0;
va_start(ap);
file = va_arg(ap, char *);
while ((args[argno++] = va_arg(ap, char *)) != (char *)0)
;
va_end(ap);
return execv(file, args);
}
|
六、 扩展与思考个数可变参数在声明时只需"..."即可;但是,我们在接受这些参数时不能"..."。va函数实现的关键就是如何得到参数列表中可选参数,包括参数的值和类型。以上的所有实现都是基于来自stdarg.h的va_xxx的宏定义。 <思考>能不能不借助于va_xxx,自己实现VA呢?,我想到的方法是汇编。在C中,我们当然就用C的嵌入汇编来实现,这应该是可以做得到的。至于能做到什么程度,稳定性和效率怎么样,主要要看你对内存和指针的控制了。
参考资料 1.IEEE和OpenGroup联合开发的Single Unix specification Ver3;BR>
2.Linux man手册;
3.x86汇编,还有一些安全编码方面的资料。
查看本文来源