C语言这种复杂宏定义,如何理解?

C语言这种复杂宏定义,如何理解?
代码来自jerryscript,一个js引擎

/**
 * A built-in object's identifier
 */
typedef enum
{
/** @cond doxygen_suppress */
#define BUILTIN(a, b, c, d, e)
#define BUILTIN_ROUTINE(builtin_id, \
                        object_type, \
                        object_prototype_builtin_id, \
                        is_extensible, \
                        lowercase_name) \
  builtin_id,
#include "ecma-builtins.inc.h"
#undef BUILTIN
#undef BUILTIN_ROUTINE
#define BUILTIN_ROUTINE(a, b, c, d, e)
#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                lowercase_name) \
  builtin_id,
#include "ecma-builtins.inc.h"
#undef BUILTIN
#undef BUILTIN_ROUTINE
/** @endcond */
  ECMA_BUILTIN_ID__COUNT /**< number of built-in objects */
} ecma_builtin_id_t;

使用方法是在.h文件中

/* The Object.prototype object (15.2.4) */
BUILTIN (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
         ECMA_OBJECT_TYPE_GENERAL,
         ECMA_BUILTIN_ID__COUNT /* no prototype */,
         true,
         object_prototype)
阅读 2.3k
1 个回答

注意当前是哪个宏定义在生效。
两次 include 宏定义是不同的。

我们只看 BUILIN ,第一次 include 展开形式是 空,所以替换后就没有了。
第二次 include ,

#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                lowercase_name) \
  builtin_id,

展开式是第一个参数(builtin_id)加一个 "," 。

所以最后展开的结果是:

/**
 * A built-in object's identifier
 */
typedef enum
{
/** @cond doxygen_suppress */
#define BUILTIN(a, b, c, d, e)
/// #include "ecma-builtins.inc.h"
// 啥都没剩下 ...
#undef BUILTIN
#undef BUILTIN_ROUTINE
#define BUILTIN(builtin_id, \
                object_type, \
                object_prototype_builtin_id, \
                is_extensible, \
                lowercase_name) \
  builtin_id,
// #include "ecma-builtins.inc.h"
/* The Object.prototype object (15.2.4) */
//BUILTIN (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
//         ECMA_OBJECT_TYPE_GENERAL,
//         ECMA_BUILTIN_ID__COUNT /* no prototype */,
//         true,
//         object_prototype)
    ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,
#undef BUILTIN
#undef BUILTIN_ROUTINE
/** @endcond */
  ECMA_BUILTIN_ID__COUNT /**< number of built-in objects */
} ecma_builtin_id_t;

还有,各种编译器大都可以数据预编译的结果,比如 gcc 的 -E 。自己搞不清楚咋展开,还可以直接让编译器帮你做,直接看结果。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进