42

在不涉及血淋淋的细节的情况下,我想使用一个#define将扩展为 a#include但“#”符号使预处理器感到困惑的宏(因为它认为我想引用一个参数。)

例如,我想做这样的事情:

#define MACRO(name) #include "name##foo"

并这样使用它:

MACRO(Test)

这将扩展到:

#include "Testfoo"

不起眼的 # 符号导致预处理器出错。MinGW 给我以下错误:

'#' is not followed by a macro parameter

我想我需要转义 # 符号,但如果这是可能的,我不会。

是的,宏确实是邪恶的......

4

8 回答 8

38

可以哈希令牌插入到预处理的令牌流中。你可以这样做:

#define MACRO(hash, name) hash include name
MACRO(#,"hello")

——扩展为:

# include "hello"

但是,该标准明确排除了对此类行的任何进一步分析,以确定是否存在预处理指令 [cpp.rescan]:

生成的完全用宏替换的预处理标记序列不会作为预处理指令处理,即使它类似于一个。

于 2011-11-27T21:39:31.587 回答
31

据我记得你不能在定义中使用另一个预处理器指令。

于 2009-07-16T06:53:14.713 回答
29

问题实际上并没有在预处理器的输出中得到 # 符号。

显然,您希望预处理器重新解析您的文件,以处理新创建的 #include 指令作为宏扩展的一部分。它不是那样工作的。如果一行以 # 开头,则它是预处理器的指令并被解释。如果一行不以 # 开头,则它只需要进行预处理器转换,包括宏替换。这是每行一次的测试。

MACRO(Test)

不以#开头。因此它不被解释为预处理器指令;相反,它受宏替换规则的约束。

于 2009-07-16T11:16:12.733 回答
11

这是因为 # 在宏中使用时具有特殊含义。

#  means quote the following token (which should be a macro parameter name)
## means concatenate the preceding and following tokens.

在您的情况下, # 后面没有正确的标记。因此,在您的情况下,我们需要经历一定程度的间接:

#define     QUOTE(name)     #name
#define     TEST(name)      QUOTE(name ## foo)

#include TEST(scot)
于 2009-07-16T07:18:59.997 回答
7

你不能那样做。预处理器指令在宏扩展之前被识别;如果宏扩展成看起来像预处理器指令的东西,则该指令将无法识别。您可以做的最好的事情是为文件名创建一个宏:

#define MACRO(name) "name##foo"
...
#include MACRO(Test)
于 2009-07-16T14:27:53.250 回答
2

可能有效(它适用于#define没有参数的常规宏,但我没有使用带参数的宏对其进行测试)。

#define MACRO(name) <name##foo>
#include MACRO(Test)
于 2009-07-16T06:52:42.047 回答
2
#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)
于 2013-01-12T14:50:53.210 回答
0
#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)

int Param;
printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);
于 2016-09-21T12:30:53.280 回答