转义#define宏中的#符号?

时间:2009-07-16 06:49:26

标签: c++ c macros c-preprocessor preprocessor-directive

我没有进入血腥细节,我想使用一个#define宏,它将扩展为#include,但'#'符号会混淆预处理器(因为它认为我想引用一个参数。)

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

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

然后使用它:

MACRO(Test)

将扩展为:

#include "Testfoo"

简陋的#符号导致预处理器进入barf。 MinGW给了我以下错误:

'#' is not followed by a macro parameter

我想我需要逃避#符号,但如果可能的话,我不会这样做。

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

8 个答案:

答案 0 :(得分:31)

可以将哈希标记插入预处理的标记流中。你可以这样做:

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

-expands to:

# include "hello"

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

  

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

答案 1 :(得分:29)

据我所知,你不能在define中使用另一个预处理器指令。

答案 2 :(得分:28)

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

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

MACRO(Test)

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

答案 3 :(得分: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)

答案 4 :(得分:6)

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

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

答案 5 :(得分:2)

这个可能有效(它适用于没有参数的常规#define宏,但我没有用带参数的宏测试它。)

#define MACRO(name) <name##foo>
#include MACRO(Test)

答案 6 :(得分:1)

#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)

答案 7 :(得分:1)

index 0: # of years,
index 1: # of days,
index 2: # of hours,
index 3: # of minutes,
index 4: # of seconds,