为什么我需要双层间接宏?

Roo*_*kie 24 c++ macros visual-c++

在:C++ FAQ - 其他技术问题 - [39.6]对于需要将两个令牌粘贴在一起的宏应该怎么做?

有人可以向我解释原因吗?我所读到的只是相信我,但我不能仅仅相信某事,因为有人这么说.

我尝试了这种方法,但我找不到任何错误:

#define mymacro(a) int a ## __LINE__
mymacro(prefix) = 5;
mymacro(__LINE__) = 5;
int test = prefix__LINE__*__LINE____LINE__; // fine
Run Code Online (Sandbox Code Playgroud)

那么为什么我需要这样做呢(引自网页):

但是,当您使用##时,需要双层间接.基本上你需要为"令牌粘贴"创建一个特殊的宏,例如:

 #define NAME2(a,b)         NAME2_HIDDEN(a,b)
 #define NAME2_HIDDEN(a,b)  a ## b 
Run Code Online (Sandbox Code Playgroud)

相信我 - 你真的需要这样做!(并且请没有人写信给我说它有时可以在没有第二层间接的情况下工作.尝试用__ LINE__连接一个符号然后看看会发生什么.)

编辑:有人也可以NAME2_HIDDEN在下面宣布之前解释他为什么使用?NAME2_HIDDEN在使用宏之前定义宏似乎更合乎逻辑.这是某种伎俩吗?

Chr*_*odd 30

C规范的相关部分:

6.10.3.1参数替换

在确定了调用类函数宏的参数之后,发生了参数替换.替换列表中的参数除非前面带有#或##预处理标记或后跟##预处理标记(见下文),否则在扩展其中包含的所有宏之后,相应的参数将替换该参数.在被替换之前,每个参数的预处理标记都被完全宏替换,好像它们形成了预处理文件的其余部分; 没有其他预处理令牌可用.

确定是否需要双重间接的关键部分是第二个句子及其中的异常 - 如果参数涉及a ###操作(例如para中的mymacroNAME2_HIDDEN),则参数中的任何其他宏都是在做#或之前没有扩展##.另一方面,如果宏体中没有###立即(如同NAME2),则扩展参数ARE中的​​其他宏.

所以它归结为你想要的 - 有时你想要所有宏扩展FIRST,然后做###(在这种情况下你想要双层间接),有时你不希望首先扩展宏(在这种情况下你可以'有双层宏,你需要直接做.)