##__VA_ARGS__与##args的用法

2,251 阅读1分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

一、__VA_ARGS__简介

C 语言中 VA_ARGS 是一个可变参数的宏,是新的 C99 规范中新增的,需要配合 define 使用,总体来说就是将左边宏中 ... 的内容原样抄写在右边 VA_ARGS 所在的位置; 举个例子:

#define myprintf(...) printf( __VA_ARGS__)
#include <stdio.h>

#define myprintf(...) printf( __VA_ARGS__)

int main()
{
    myprintf("123123456\n");
    return 0;
}

book@ubuntu:~/temp$ gcc -o hello_arg hello_arg.c 
book@ubuntu:~/temp$ ./hello_arg
123123456
book@ubuntu:~/temp$ 

二、__VA_ARGS__宏输出可变参数

#include <stdio.h>

#define myprintf(fm, ...) printf(fm,__VA_ARGS__) 


int main()
{
    //输出可变参数
    myprintf("0123456789,%d%s\r\n",1,"sd"); //OK
    //myprintf("987654321");    //输出字符串常量报错
    return 0;
}
book@ubuntu:~/temp$ gcc -o hello_arg hello_arg.c 
book@ubuntu:~/temp$ ./hello_arg
0123456789,1sd

从这里可以看到这种写法只支持可变参数,不支持字符串常量。

三、##VA_ARGS

##__VA_ARGS__使用如下:

#define myprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)

如果可变参数被忽略或为空,## 操作将使预处理器(preprocessor)去除掉它前面的那个逗号. 如果你在宏调用时,确实提供了一些可变参数,GNU CPP 也会工作正常,它会把这些可变参数放到逗号的后面。 ##__VA_ARGS__使用

#include <stdio.h>

#define myprintf(fm, ...) printf(fm,##__VA_ARGS__) 


int main()
{
    //输出可变参数
    myprintf("0123456789,%d%s\r\n",1,"sd"); //OK
    myprintf("987654321\r\n");    //输出字符串常量正常
    return 0;
}
book@ubuntu:~/temp$ gcc -o hello_arg hello_arg.c 
book@ubuntu:~/temp$ ./hello_arg
0123456789,1sd
987654321

同样的例子从上面的代码可以看出,使用 ##VA_ARGS 完美兼容可变参数和字符串常量输出;

四、gcc 复杂宏##args用法

#define debug(format, args...) printf(format, ##args) #的作用 : 连接两个宏,如果可变参数被忽略或为空,"##"操作将使预处理器(preprocessor)去除掉它前面的那个逗号,编译不会报错. 本文中涉及的##__VA_ARGS__与##args在代码中常见的写法:

#define print_LOG(level, fmt, ...)       printf("[%s][%d]"fmt"\n", __FUNCTION__, __LINE__, ##__VA_ARGS__)

#define print_LOG(level, fmt, args...)   SYS_LOG("[WIFI]", level, fmt,  ##args)