Apr 27
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// 一般使用方法
// #include <stdarg.h>
// void some_function(type1 var1,type2 last,...)
// {
//     va_list ap;
//     va_start(ap,last);
//     ...
//     typex var=va_arg(ap,typex);
//     ...
//     va_end;
//     return;
// }
 
// stdarg.h
// va_list 其实就是一个字节指针
typedef char *va_list;
 
// _va_size(type)总是4的倍数,因为系统在处理压栈的时候总是4字节对齐的。
#define __va_size(type) \
    (((sizeof(type) + sizeof(long) - 1) / sizeof(long)) * sizeof(long))
 
// last是最后一个压栈的参数(也是第一个已知类型的参数),ap指向其后一个参数,即可变参数开始的地方。
#define va_start(ap, last) \
    ((ap) = (va_list)&(last) + __va_size(last))
 
// 得到类型为type的参数,并使ap指向下一个参数。
#define va_arg(ap, type) \
    (*(type *)((ap) += __va_size(type), (ap) - __va_size(type)))
 
// 为了结构的完整性而定义。
#define va_end(ap)  ((void)0)