如何理解这样的C宏扩展

时间:2012-09-08 03:31:56

标签: c macros

宏定义:

#define HTTP_ERRNO_MAP(XX)                                           \
  /* No error */                                                     \
  XX(OK, "success")                                                  \
                                                                     \
  /* Callback-related errors */                                      \
  XX(CB_message_begin, "the on_message_begin callback failed")       \
  XX(CB_url, "the on_url callback failed")                           \


/* Define HPE_* values for each errno value above */
#define HTTP_ERRNO_GEN(n, s) HPE_##n,
enum http_errno {
  HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};
#undef HTTP_ERRNO_GEN

用“gcc -E”扩展后,

enum http_errno {
  HPE_OK, HPE_CB_message_begin, HPE_CB_url,};

宏如何扩展到结果?

1 个答案:

答案 0 :(得分:1)

HTTP_ERRNO_MAP(XX)会将XX替换为HTTP_ERRNO_GEN,因此会将HTTP_ERRNO_GEN(n, s)宏调用3次:

HTTP_ERRNO_GEN(OK, "success")
HTTP_ERRNO_GEN(CB_message_begin, "the on_message_begin callback failed")
HTTP_ERRNO_GEN(CB_url, "the on_url callback failed")

HTTP_ERRNO_GEN(n, s)只需获取第一个参数的实际文本,并将其(##n)连接到前面的HPE和末尾的逗号。因此,上面的三个命令将产生以下三个输出:

HPE_OK,
HPE_CB_message_begin,
HPE_CB_url,

因此,当由预处理器扩展时,

enum http_errno {
  HTTP_ERRNO_MAP(HTTP_ERRNO_GEN)
};

成为(+ - 空白):

enum http_errno {
   HPE_OK,
   HPE_CB_message_begin,
   HPE_CB_url,
};