双井号(##)在宏中是什么意思?

12
在下面的代码中,##是用来做什么的?
 #define MAKE_TYPE(myname) \
 typedef int myname ## Id; \

本质上是 SO 1489932 C 预处理器和连接 的副本。 - Jonathan Leffler
2个回答

22
在宏中,##表示连接。在这里,MAKE_TYPE(test)将展开为:typedef int testId。 根据16.3.3(##运算符)的规定: 对于对象式和函数式的宏调用,在重新检查替换列表以查找更多要替换的宏名称之前,将删除替换列表中每个非参数中的##预处理标记,并将前面的预处理标记与后面的预处理标记连接起来。

4
在重新检查替换列表之前,我会在*之前加下划线。如果您编写MAKE_TYPE(OBJECT(Foo)),那么您将拥有typedef int OBJECT(Foo)Id;...这显然是无效的。处理宏是很麻烦的,最好避免使用,特别是在这种仅混淆事情的琐碎情况下。 - Matthieu M.

5

icecrime是正确的,但在定义中需要指出的重要一点是,标记必须是有效的预处理标记。例如:

#define CONCAT(a,b) a ## b
CONCAT(ClassyClass, <int>); // bad, <int> is not a valid preprocessing token
CONCAT(Symbol, __LINE__); // valid as both are valid tokens

1
那在几年前给我带来了很大的挫败感,因为我想要将三个东西连接在一起,但既不是第一对也不是最后一对的组合都不是有效的预处理标记。 - David Thornley
很好的观点,但不是答案。应该作为评论发表在icecrime的下面。 - underscore_d

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接