有没有办法在另一个#define中进行#define?

时间:2010-07-22 22:32:58

标签: c++ c-preprocessor

我知道我正试图在腿上射击自己;但是,这将允许我使其余(大量)代码更小,更易读。

在另一个预处理器宏中创建预处理器宏有什么棘手的方法吗?

这是一个例子,我正在寻找什么。我的真实场景更复杂

// That's what I want to do and surely C++ doesn't like it.
#define MACROCREATER(B) #define MACRO##B B+B

void foo()
{
 MACROCREATOR(5) // This should create new macro (#define MACRO5 5+5)

 int a = MACRO5; // this will use new macro
}

6 个答案:

答案 0 :(得分:44)

C ++标准说(16.3.4.3):

  

结果完全   宏替换的预处理令牌   序列[宏扩展...的...]不作为a处理   预处理指令,即使它   类似于......

所以不,没有'官方'的方式来实现你想要的宏。

答案 1 :(得分:13)

没有。即使宏扩展为看起来像预处理指令的东西,扩展也不会被评估为预处理指令。

答案 2 :(得分:7)

作为上述答案的补充,如果确实想要对源文件进行两次预处理 - 这几乎肯定是而不是您实际想做的事情 - 你可以随时调用你的编译器:

g++ -E input.cpp | g++ -c -x c++ - -o output.o

即,通过预处理器运行文件,然后通过管道通过完整的编译例程运行预处理的输出,包括第二个预处理步骤。为了让它具有相当好的工作机会,我想你在定义和使用你的宏时必须要非常小心,总而言之,它很可能不值得麻烦和增加构建时间。

如果您真的需要宏,请使用标准的基于宏的解决方案。如果您真的想要编译时元编程,请使用模板。

在一个稍微相关的说明中,这让我想起了光线跟踪语言POV-Ray大量使用了相当复杂的预处理语言这一事实​​,其中流量控制指令如#while允许条件重复,编译 - 时间计算和其他这样的好东西。在C ++中是这样的,但事实并非如此,所以我们只是采取另一种方式。

答案 3 :(得分:3)

没有。预处理器是单通道的。它没有重新评估宏扩展。

答案 4 :(得分:3)

答案 5 :(得分:3)

看看m4。它类似于cpp,但递归并且功能更强大。我用m4为汇编程序创建了一种结构化语言,例如

  cmp r0, #0
  if(eq)
    mov r1, #0
  else
    add r1, #1
  end

“if”,“else”和“end”是对我编写的m4宏的调用,它们生成跳转和标签,其余的是本机程序集。为了嵌套这些if / else / end结构,你需要在宏中进行定义。