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

发布于 2024-08-30 02:37:08 字数 857 浏览 6 评论 0原文

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

#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

I have some fairly generic code which uses preprocessor macros to add a certain prefix onto other macros. This is a much simplified example of what happens:

#define MY_VAR(x) prefix_##x

"prefix_" is actually defined elsewhere, so it will be different each time the file is included. It works well, but now I have some code I would like to skip if one of the tokens doesn't exist, but this doesn't work:

#if defined MY_VAR(hello)

What I want it to expand to is this:

#ifdef prefix_hello

But I can't figure out how. I need to use the MY_VAR() macro to do the expansion, so I can't just hardcode the name. (It's actually for some testing code, the same code gets included with a different prefix each time to test a bunch of classes, and I want to skip a couple of tests for a handful of the classes.)

Is this possible with the C++ preprocessor?

Update:

Here is some semi-compilable code to demonstrate the problem further: (to avoid squishing it into the comments below)

#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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

眼角的笑意。 2024-09-06 02:37:08

您的程序是否比这个问题描述的更多?该指令

#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_ 的操作。 (未定义的标识符将替换为零。)

Is there more to your program than this question describes? The directive

#define MY_VAR(x) prefix_##x

defines exactly one preprocessor identifier. The call

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

simply goes in one end of the preprocessor and comes out the other without defining anything.

Without some other magic happening, you can't expect the preprocessor to remember what arguments have been passed into what macros over the course of the preceding source code.

You can do something like

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

to query whether the prefix currently has the particular value prefix_. (Undefined identifiers are replaced with zero.)

倾`听者〃 2024-09-06 02:37:08

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

I think you've got to the level where the preprocessor won't cut it any more; it's really quite simple-minded. Have you considered using templates instead? (Assuming that they're meaningful for your problem, of course.)

幻梦 2024-09-06 02:37:08

这是对您更新的问题的回应。对于每个可能的 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' 已定义但未使用。)

This is in response to your updated question. For each possible hello_test, after any possibility of #define hello_test "blah blah", add the lines:

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

Then change your test to:

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

Or, as an alternative, before all the #define ..."blah blah"'s, add the line(s):

static const char * const MY_VAR(test);

for all possible values of MY_VAR and test. This will avoid hard-coding "hello_test". (The second const here removes the gcc warning: ‘hello_test’ defined but not used.)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文