0%

GCC中常用的宏定义

最近在看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 },
     ...
   };