C宏定义小记

由一段宏定义代码开始:

1
2
3
4
5
6
7
#define SPP_LOG_ERR(fmt, args...) do{\
SPP_SERVERBASE->log_.LOG_P(tbase::tlog::LOG_ERROR, "[%d][%s:%s:%d][LOG_ERROR]"fmt"\n",g_pid,__FILE__,__FUNCTION__,__LINE__, ##args);\
}while(false)
#define SPP_LOG_DBG(fmt, args...) do{\
SPP_SERVERBASE->log_.LOG_P(tbase::tlog::LOG_DEBUG, "[%d][%s:%s:%d][LOG_DEBUG]"fmt"\n",g_pid,__FILE__,__FUNCTION__,__LINE__, ##args);\
}while(false)

宏定义字符串拼接

  • 临近字符串自动拼接
  • “aaaaaaa””bbbbbb””cccccc”会被自动合成:”aaaaaaabbbbbbcccccc”

多参数处理

C C++带多个参数的宏(…与VA_ARGS详解)

  1. 环境
    gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
    2.’…’与VA_ARGS
    这里的…代表多个参数,在宏展开时,编译器会经…的参数替换VA_ARGS

例1:main.c文件敲入如下代码

1
2
3
4
5
6
#define debug(format, ...) printf (format, __VA_ARGS__)
#include <stdio.h>
void main(){
debug("Hello %s\n", "world");
}

使用预编译命令gcc -E main.c -o main.i看看展开后是什么效果:

1
2
3
void main(){
printf ("Hello %s\n", "world");
}

3. 多参数别名

__VA_ARGS__这个名字似乎很难写,gcc支持另一种更加人性化的写法:

例2:

1
2
3
4
5
6
#define debug(format, args...) printf (format, args)
#include <stdio.h>
void main(){
debug("Hello %s\n", "world");
}

展开后效果跟第一种写法是一样的:

1
2
3
void main(){
printf ("Hello %s\n", "world");
}

4. 空参数与##

前面两个例子都传入了两个参数,如果…没有传进参数会发生什么事情呢:

1
2
3
4
5
6
7
8
#define debug(format, ...) printf (format, __VA_ARGS__)
#include <stdio.h>
void main(){
debug("Hello world\n");
}

展开后:

1
2
3
void main(){
printf ("Hello world\n", );
}

可以看到Hello world后面带来一个,
这个时候就会导致编译出错。##的出现就是为了解决这个问题:
当…没有传进参数时,预编译器会将最后面的,删除

1
2
3
4
5
6
#define debug(format, ...) printf (format, ##__VA_ARGS__)
#include <stdio.h>
void main(){
debug("Hello world\n");
}

展开后效果:

1
2
3
void main(){
printf ("Hello world\n");
}

本文标题:C宏定义小记

文章作者:Yang Shuai

发布时间:2019年06月04日 - 08:06

最后更新:2019年06月04日 - 08:06

原始链接:https://ysbbswork.github.io/2019/06/04/C宏定义小记/

许可协议: 署名-非商业性使用-禁止演绎 4.0 国际 转载请保留原文链接及作者。

坚持原创技术分享,您的支持将鼓励我继续创作!