glibc 中确定宏参数个数的宏__SYSCALL_NARGS 及 可变参数宏__VA_ARGS__

读 glibc 中 关于 socket 系统调用实现的部分,然后看到了这里,写在这里做份一份笔记。

#define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
#define __SYSCALL_NARGS(...) \
  __SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)
#define __SYSCALL_CONCAT_X(a,b)     a##b
#define __SYSCALL_CONCAT(a,b)       __SYSCALL_CONCAT_X (a, b)
#define __SYSCALL_DISP(b,...) \
  __SYSCALL_CONCAT (b,__SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__)

__VA_ARGS__ 代表首层的所有的宏参数,在
__SYSCALL_NARGS_X 中做参数替换,而 __SYSCALL_NARGS_X 通过额外增加参数(7,6,5,4,3,2,2,0,)来确定
__VA_ARGS__  中究竟传进来多少个参数,从而拼接出究竟要调用哪一个类型的函数

测试代码如下

  #include <stdio.h>                                                                                                                                  
  #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n                                                                                                 
  #define __SYSCALL_NARGS(...) \                                                                                                                      
  __SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)  
int main(int argc,char* argv[]) { int paramCnt1 = __SYSCALL_NARGS(1); int paramCnt2 = __SYSCALL_NARGS(1,2); int paramCnt3 = __SYSCALL_NARGS(1,2,3); int paramCnt4 = __SYSCALL_NARGS(1,2,3,4);
printf("param cnt1:%d\n", paramCnt1); printf("param cnt2:%d\n", paramCnt2); printf("param cnt3:%d\n", paramCnt3); printf("param cnt4:%d\n", paramCnt4); return 0; }

测试代码结果如下:






posted @ 2018-07-28 07:57  _AK47_SPACE  阅读(190)  评论(0编辑  收藏  举报