2010-11-19 30 views
12

在下面的代码中,##有什么作用?宏中的双重散列(##)是什么意思?

#define MAKE_TYPE(myname) \ 
typedef int myname ## Id; \ 
+0

本质[SO 1489932 C预处理和串联](http://stackoverflow.com/questions/1489932/c-preprocessor-and-concatenation/)的副本 – 2010-11-20 03:00:38

回答

22

宏中的##是串联。在这里,MAKE_TYPE(test)将扩展为:typedef int testId

从16.3.3(##的操作者):

对于这两种样函数对象样和 宏调用,进行复核之前 替换列表为 多个宏名称来替换,每个一个##在替换列表(从 参数不)预处理记号 被删除,并且前述 预处理标记的 实例级联 具有以下预处理记号

+4

我要强调前的*替换列表被重新检查*。如果你写'MAKE_TYPE(OBJECT(Foo))',那么你将有'typedef int OBJECT(Foo)Id;'......这显然是无效的。处理宏是复杂的,并且最好避免,尤其是对于只会混淆事物的这种微不足道的情况。 – 2010-11-19 15:22:45

4

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

几年前,这让我感到非常沮丧,因为我想将三件事合并在一起,而第一对和最后一对的组合都不是有效的预处理标记。 – 2010-11-19 18:04:16

+0

伟大的一点,但不是一个答案。应该是对icecrime的评论。 – 2016-07-29 15:59:47