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__  中究竟传进来多少个参数,从而拼接出究竟要调用哪一个类型的函数

测试代码如下
  1 #include <stdio.h>                                                                                                                                                                                                                                                                                                                    |   " Press <F1> to display hel
  2                                                                                                                                                                                                                                                                                                                                       |
  3 #define __SYSCALL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n                                                                                                                                                                                                                                                                                    |-  var_num_macro.c (/home/sunz
  4 #define __SYSCALL_NARGS(...) \                                                                                                                                                                                                                                                                                                        ||-   macro
  5   __SYSCALL_NARGS_X (__VA_ARGS__,7,6,5,4,3,2,1,0,)                                                                                                                                                                                                                                                                                    |||     __SYSCALL_NARGS_X
  6                                                                                                                                                                                                                                                                                                                                       |||     __SYSCALL_NARGS
  7                                                                                                                                                                                                                                                                                                                                       ||
  8                                                                                                                                                                                                                                                                                                                                       ||-   function
  9 int main(int argc,char* argv[]){                                                                                                                                                                                                                                                                                                      |||     main
 10                                                                                                                                                                                                                                                                                                                                       |
 11     int paramCnt1 = __SYSCALL_NARGS(1);                                                                                                                                                                                                                                                                                               |   ~
 12     int paramCnt2 = __SYSCALL_NARGS(1,2);                                                                                                                                                                                                                                                                                             |   ~
 13     int paramCnt3 = __SYSCALL_NARGS(1,2,3);                                                                                                                                                                                                                                                                                           |   ~
 14     int paramCnt4 = __SYSCALL_NARGS(1,2,3,4);                                                                                                                                                                                                                                                                                         |   ~
 15                                                                                                                                                                                                                                                                                                                                       |   ~
 16     printf("param cnt1:%d\n", paramCnt1);                                                                                                                                                                                                                                                                                             |   ~
 17     printf("param cnt2:%d\n", paramCnt2);                                                                                                                                                                                                                                                                                             |   ~
 18     printf("param cnt3:%d\n", paramCnt3);                                                                                                                                                                                                                                                                                             |   ~
 19     printf("param cnt4:%d\n", paramCnt4);                                                                                                                                                                                                                                                                                             |   ~
 20                                                                                                                                                                                                                                                                                                                                       |   ~
 21     return 0;                                                                                                                                                                                                                                                                                                                         |   ~
 22 }     

测试代码结果如下:





原文地址:https://www.cnblogs.com/ak47-space/p/9380535.html

时间: 2024-10-10 23:47:16

glibc 中确定宏参数个数的宏__SYSCALL_NARGS 及 可变参数宏__VA_ARGS__的相关文章

C#通过反射获取类中的方法和参数个数,反射调用方法带参数

using System; using System.Reflection; namespace ConsoleApp2 { class Program { static void Main(string[] args) { //反射获取 命名空间+类名 string className = "ConsoleApp2.ClassSample"; string methodName = "test1"; //传递参数 Object[] paras = new Obje

一、javaSE (十六)List的子类、泛型、增强for循环、静态导入、可变参数

1:List的子类(掌握) (1)List的子类特点 ArrayList: 底层数据结构是数組,查迿快,增删慢 线程不安全,效率高 Vector: 底层数据结构是数組,查询快,增删慢 线程安全,效率低 LinkedList: 底层数据结枃是链表,查询慢,增删快 线程不安全,效率高 (2)Arraylist A:没有特有功能需要学习 B:案例 a: Arraylist存储字符串并遍历 b: Arraylist存储自定义对象并遍历 (3)Vector A:特有功能 a:添加: public void

编写一个可变参数的C函数——头文件stdarg.h中宏va_start ,va_arg和va_end的应用

我们在C语言编程中会遇到一些参数个数可变的函数,例如printf()这个函数,它的定义是这样的:int printf( const char* format, ...);它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的,例如我们可以有以下不同的调用方法:printf("%d",i);printf("%s",s);printf("the number is %d ,string is:%s", i, s);究竟如何写可变参数的

C语言中宏定义之 ## 用于可变参数

GCC 支持复杂的宏,它使用一种不同的语法,使你可以给可变参数一个名字,如同其它参数一样,比如: 引用 #define debug(format, args...) fprintf(stderr, format, args) 这种定义可读性更强,也更容易描述.完整测试代码: 引用 #include <stdio.h> #define debug(format, args...) fprintf(stderr, format, args) int main(){    char a[20] = 

C中参数个数可变的函数

一.什么是可变参数 我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为: int printf( const char* format, ...); 它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(用三个点"-"做参数占位符),实际调用时可以有以下的形式: printf("%d",i); printf("%s",s); printf("the number is %d ,s

嵌入式C语言自我修养 12:有一种宏,叫可变参数宏

12.1 什么是可变参数宏 在上面的教程中,我们学会了变参函数的定义和使用,基本套路就是使用 va_list.va_start.va_end 等宏,去解析那些可变参数列表我们找到这些参数的存储地址后,就可以对这些参数进行处理了:要么自己动手,自己处理:要么继续调用其它函来处理. void print_num(int count, ...) { va_list args; va_start(args,count); for(int i = 0; i < count; i++) { printf(&qu

C语言中可变参数的使用方法

[温馨提示: 以下内容均来自网友的无私奉献或书本的摘抄,在此表示感谢!] 我们在C语言编程中会遇到一些参数个数可变的函数,例如printf()这个函数,其定义为: int printf( const char* format, ...); 它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的,例如我们可以有以下不同的调用方法: printf("%d",i); printf("%s",s); printf("the number is %d

c 中可变参数的实现

我们在C语言编程中有时会遇到一些参数个数可变的函数,例如printf()函数,其函数原型为:     例一: int   printf(   const   char*   format,   ...);它除了有一个参数format固定以外,后面跟的参数的个数和类型是可变的(用三个点“…”做参数占位符),实际调用时可以有以下的形式: printf("%d",i);        printf("%s",s);     printf("the   numbe

C语言中可变参数函数实现原理

C函数调用的栈结构 可变参数函数的实现与函数调用的栈结构密切相关,正常情况下C的函数参数入栈规则为__stdcall, 它是从右到左的,即函数中的最右边的参数最先入栈.例如,对于函数: void fun(int a, int b, int c) { int d; ... } 其栈结构为 0x1ffc-->d 0x2000-->a 0x2004-->b 0x2008-->c 对于在32位系统的多数编译器,每个栈单元的大小都是sizeof(int), 而函数的每个参数都至少要占一个栈单