捣鼓一些事情,跟c库函数int open(const char *pathname, int flags, …)打交道,也有一丢丢像open()一样实现可变参数的需求。因此了解了下c中的可变参数函数。
主要涉及va_list, va_start, va_arg, va_end和C99扩展可变参数宏__VA_ARGS__,网上资料很多了,这里只想记下计算可变参数个数的小trick,参考了这篇Overloading Functions in C
自己写的额小代码:
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#define bar(fmt, ...) printf(fmt, __VA_ARGS__);
/*
void bar(const char *fmt, ...)
{
printf(fmt, __VA_ARGS__); // error
}
*/
// 只能计算最多2个参数的情况,再多就错了。当然也可以照此扩展,使之能够计算更多参数
#define COUNT_PARMS(...) COUNT_PARMS_AUX(__VA_ARGS__, 2, 1)
#define COUNT_PARMS_AUX(_2, _1, _, ...) _
#define foo(name, ...) do_foo(COUNT_PARMS(__VA_ARGS__), name, __VA_ARGS__)
static void do_foo(int count, const char *pathname, ...)
{
va_list ptr;
int a = 0, b = 0;
va_start(ptr, pathname);
switch (count)
{
case 1:
a = va_arg(ptr, int);
break;
case 2:
a = va_arg(ptr, int);
b = va_arg(ptr, int);
break;
default:
break;
}
va_end(ptr);
printf("%s, %d, %d\n", pathname, a, b);
}
int main()
{
bar("%d, %s\n", 1, "haha");
foo("haha", 1);
foo("haha", 1, 2);
foo("haha", 1, 2, 3); // meaningless
return 0;
}
参考
1. Overloading Functions in C,http://locklessinc.com/articles/overloading/,2016.11.16.