C++ 在#define 宏中转义# 符号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1135822/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 18:58:01  来源:igfitidea点击:

Escaping a # symbol in a #define macro?

c++cmacrosc-preprocessorpreprocessor-directive

提问by Rob

Without going into the gory details I want to use a #definemacro that will expand to a #includebut the '#' sign is confusing the preprocessor (as it thinks I want to quote an argument.)

无需深入细节,我想使用一个#define宏,该宏将扩展为 a#include但“#”符号使预处理器感到困惑(因为它认为我想引用一个参数。)

For example, I want to do something like this:

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

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

And use it thus:

并使用它:

MACRO(Test)

Which will expand to:

这将扩展到:

#include "Testfoo"

The humble # sign is causing the preprocessor to barf. MinGW gives me the following error:

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

'#' is not followed by a macro parameter

'#' is not followed by a macro parameter

I guess I need to escape the # sign but I don't if this is even possible.

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

Yes, macros are indeed evil...

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

采纳答案by EFraim

As far as I remember you cannot use another preprocessor directive in define.

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

回答by ybungalobill

It ispossible to insert a hash token into the preprocessed token stream. You can do it as follows:

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

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

—expands to:

——扩展为:

# include "hello"

However, the standard explicitly rules out any further analysis of such line for the existence of preprocessing directives [cpp.rescan]:

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

The resulting completely macro-replaced preprocessing token sequence is not processed as a preprocessing directive even if it resembles one.

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

回答by MSalters

The problem isn't actually getting a # symbol in the output of your preprocessor.

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

Apparently you want the preprocessor to reparse your file, to deal with newly created #include directives as part of macro expansion. It doesn't work that way. If a line starts with #, it's an instruction for the preprocessor and interpreted. If a line doesn't start with #, it's only subject to preprocessor transformation including macro substitution. This is a once-per-line test.

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

MACRO(Test)

does not start with #. Therefore it is not interpreted as a preprocessor directive; instead it's subject to macro replacement rules.

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

回答by Martin York

This is because the # has special meaning when used in a macro.

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

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

In your situation the # is not followed by a proper token. So in your situation we need to go through a level of indirection:

在您的情况下,# 后面没有正确的标记。所以在你的情况下,我们需要通过一个间接级别:

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

#include TEST(scot)

回答by John Bode

You can't do that. Preprocessor directives are recognized before macro expansion; if the macro expands into something that looks like a preprocessor directive, that directive will not be recognized. The best you can do is create a macro for the file name:

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

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

回答by David F.

#define HASH_SIGN #
BOOST_PP_CAT(HASH_SIGN, include)

回答by Sam Harwell

This mightwork (it works for regular #definemacros with no parameters, but I haven't tested it with macros with parameters).

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

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

回答by user6858363

#define PARAM_NAME Param
#define GETNAME_(a) #a
#define GETNAME(a) GETNAME_(a)

int Param;
printf("%s = %i\n", GETNAME(PARAM_NAME), PARAM_NAME);