6

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

#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
4

3 回答 3

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_。(未定义的标识符被零替换。)

于 2010-04-24T07:37:52.520 回答
2

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

于 2010-04-24T07:07:24.023 回答
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 ..."blah blah" 之前,添加以下行:

static const char * const MY_VAR(test);

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

于 2010-05-03T01:33:26.600 回答