最近在看Facebook的基于C++11写的一个常用工具库folly,包括内存分配、原子锁等等。
源码里有一些常用的宏定义,大致归纳一下,方便阅读(大部分来自gcc.gnu.org)。
Variadic Macros(c99特性)
可以这样定义一个可变长参数函数:
#define eprintf(...) fprintf(stderr, __VA_ARGS__)
#define eprintf(format, ...) fprintf(stderr, format, __VA_ARGS__)
也可以这样(c++写法,如果需要考虑兼容性,c++中只应该使用该写法,c99只使用**__VA_ARGS__**):
#define eprintf(args...) fprintf(stderr, args)
但注意这种写法就不能在后面增加**__VA_ARGS__**了。
假如你的参数可能为空,可以这样写:
#define eprintf(format, ...) fprintf (stderr, format, ##__VA_ARGS__)
这样当**__VA_ARGS__为空时,__VA_ARGS__**前的『,』会被删除,例如:
eprintf ("success!\n")
==> fprintf(stderr, "success!\n");
使用Variadic Macros还有一些细节上的问题,见Variadic Macros末尾几段。
Stringification
# 定义
(hash mark)表示将随后的参数转化为字符串字面量,一般用在输出中:
#define xstr(s) str(s)
#define str(s) #s
#define foo 4
str (foo)
==> "foo"
xstr (foo)
==> xstr (4)
==> str (4)
==> "4"
xstr定义用于得到参数的值。
## 定义
用于连接字符串字面量(最好前后加空格),可以这样用:
#define COMMAND(NAME) { #NAME, NAME ## _command }
struct command commands[] =
{
COMMAND (quit),
COMMAND (help),
...
};
等价于:
struct command
{
char *name;
void (*function) (void);
};
struct command commands[] =
{
{ "quit", quit_command },
{ "help", help_command },
...
};