关于预处理期间MACROS的扩展

时间:2015-11-17 19:45:37

标签: c++ c compilation macros nested

我有一个现有的MACRO,需要两个实体。 MACRO_1(x,y)

我想定义2个这样的新宏: - ROOT_MACRO(z,x__y) = z

在这里,我希望使用MACRO_2在预处理中评估MACRO_2(z) 对于前者我的cpp文件看起来像这样: -

MACRO_1(x,y)

ROOT_MACRO(z,x__y) ==>应扩展到 MACRO_2(p)

//稍后在.cpp文件中

MACRO_1(x,y)

ROOT_MACRO(p,x__y) ==>应该扩展到 require 'rails_helper'

有没有办法实现这个目标?我希望这个问题很清楚。

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您需要以下内容:

#define MACRO_2(p) #define MACRO_2_DEFINED p
#define MACRO_1(x,y) ROOT_MACRO(MACRO_2_DEFINED,x__y)

但是cpp(c预处理器)一次性工作,你不能define a define。如果能够更改构建系统,则可以在将代码发送到cpp之前使用m4。以下是使用m4的示例:

#define ROOT_MACRO(x,y) This is the root macro with arguments x and y
define(`MACRO_2',`#undef MACRO_2_DEFINED
#define MACRO_2_DEFINED $1')
define(`MACRO_1', `ROOT_MACRO(MACRO_2_DEFINED, $1__$2)')

MACRO_2(z)
MACRO_1(x,y)

MACRO_2(p)
MACRO_1(x,y)

然后在上面的文件上运行m4(例如$m4 foo.c)会产生:

#define ROOT_MACRO(x,y) This is the root macro with arguments x and y



#undef MACRO_2_DEFINED
#define MACRO_2_DEFINED z
ROOT_MACRO(MACRO_2_DEFINED, x__y)

#undef MACRO_2_DEFINED
#define MACRO_2_DEFINED p
ROOT_MACRO(MACRO_2_DEFINED, x__y)

在上面的代码上运行cpp(例如$m4 foo.c | cpp -)会产生:

# 1 "<stdin>"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "<stdin>"






This is the root macro with arguments z and x__y



This is the root macro with arguments p and x__y

答案 1 :(得分:0)

@davir是对的,你不能#define一个定义。使用标准预处理器可以获得的最佳效果如下:

#define  M1(x,y) MACRO_BASE(M2, x##__##y)

...
#define M2 z
M1(x,y) //# expands to MACRO_BASE(z,x__y)

...//later
#define M2 p
M1(x,y) //# expands to MACRO_BASE(p,x__y)

如果zp是固定类型的值,那么您可能会遇到类似以下内容:

#define M2(v) thetype_t current_m2__ = v
#define M1(x,y) MACRO_BASE(current_m2__, x##__##y)

只要您在与M1相同的范围内始终只有一次呼叫M2,这可能会起作用。

但为什么不把M2和M1之类的电话合并为#define M(v,x,y) MACRO_BASE(v,x##__##y)