你如何在#ifdef中执行宏扩展?

时间:2010-04-24 06:47:13

标签: c++ macros c-preprocessor stringification

我有一些相当通用的代码,它使用预处理器宏在其他宏上添加某个前缀。这是一个简单的例子:

#define MY_VAR(x) prefix_##x

“prefix_”实际上是在其他地方定义的,因此每次包含文件时它都会有所不同。它运行良好,但现在我有一些代码我想跳过如果其中一个令牌不存在,但这不起作用:

#if defined MY_VAR(hello)

我希望它扩展到:

#ifdef prefix_hello

但我无法弄清楚如何。我需要使用MY_VAR()宏来进行扩展,所以我不能只是对名称进行硬编码。 (实际上对于一些测试代码,每次测试一堆类时,相同的代码都包含不同的前缀,我想跳过几个类的几个测试。)

这可以用C ++预处理器吗?

更新

以下是一些可以进一步证明问题的半可编辑代码:(避免将其压缩到下面的评论中)

#define PREFIX hello

#define DO_COMBINE(p, x)  p ## _ ## x
#define COMBINE(p, x)     DO_COMBINE(p, x)
#define MY_VAR(x)         COMBINE(PREFIX, x)

// MY_VAR(test) should evaluate to hello_test

#define hello_test "blah blah"

// This doesn't work
#ifdef MY_VAR(test)
  printf("%s\n", MY_VAR(test));
#endif

3 个答案:

答案 0 :(得分:3)

您的计划还有比此问题更多的内容吗?指令

#define MY_VAR(x) prefix_##x

确切地定义了一个预处理器标识符。电话

blah ^&* blah MY_VAR(hello) bleh <>? bleh

简单地进入预处理器的一端,然后在没有定义任何内容的情况下从另一端出来。

如果没有其他一些魔法发生,你不能指望预处理器记住在前面的源代码过程中哪些参数传递到了哪些宏。

您可以执行类似

的操作
#define prefix_test 1
#if MY_VAR(test) == 1
#undef prefix_test // optional, "be clean"
...
#endif
#undef prefix_test

查询前缀当前是否具有特定值prefix_。 (未定义的标识符将替换为零。)

答案 1 :(得分:2)

我认为你已达到预处理器不再削减它的水平;它真的很简单。您是否考虑过使用模板? (当然,假设它们对你的问题有意义。)

答案 2 :(得分:0)

这是对您更新的问题的回应。对于每个可能的hello_test,之后任何可能的#define hello_test“blah blah”,添加以下行:

#ifndef hello_test
#define hello_test (char*)0
#endif

然后将测试更改为:

if (MY_VAR(test))
    printf("%s\n", MY_VAR(test));

或者,作为替代方案,之前所有#define ......“等等等等”,添加行:

static const char * const MY_VAR(test);

对于MY_VAR的所有可能值并进行测试。这将避免硬编码“hello_test”。 (第二个const在这里删除了gcc警告:'hello_test'已定义但未使用。)