如何在#ifdef 中执行宏扩展?
我有一些相当通用的代码,它使用预处理器宏将某个前缀添加到其他宏上。这是所发生情况的一个非常简单的示例:
#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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您的程序是否比这个问题描述的更多?该指令
恰好定义了一个预处理器标识符。该调用
只是简单地进入预处理器的一端并从另一端出来,而无需定义任何内容。
如果没有其他魔法发生,您不能指望预处理器记住在前面的源代码过程中哪些参数被传递到哪些宏中。
您可以执行类似
查询前缀当前是否具有特定值
prefix_
的操作。 (未定义的标识符将替换为零。)Is there more to your program than this question describes? The directive
defines exactly one preprocessor identifier. The call
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
to query whether the prefix currently has the particular value
prefix_
. (Undefined identifiers are replaced with zero.)我认为你已经达到了预处理器不再削减它的水平;实在是相当简单。您是否考虑过使用模板来代替? (当然,假设它们对您的问题有意义。)
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.)
这是对您更新的问题的回应。对于每个可能的 hello_test,在 #define hello_test "blah blah" 的任何可能性之后,添加以下行:
然后将您的测试更改为:
或者,作为替代方案,在所有#define ...“blah blah”,添加行:
对于 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:
Then change your test to:
Or, as an alternative, before all the #define ..."blah blah"'s, add the line(s):
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.)