2011-11-27 100 views
15

当我使用此代码:“#define STR(x)#x”和“#define STR(x)VAL(x)”与“#define VAL(x)#x”之间的区别是什么?

#include <stdio.h> 
#define STR(x) #x 

int main(void) 
{ 
    printf(__FILE__ STR(__LINE__) "hello!\n"); 
    return 0; 
} 

它打印

hello.c__LINE__hello! 

但是当我使用这个:

#include <stdio.h> 
#define STR(x) VAL(x) 
#define VAL(x) #x 

int main(void) 
{ 
    printf(__FILE__ STR(__LINE__) "hello!\n"); 
    return 0; 
} 

它打印

hello.c7hello! 

有什么区别其中,宏参数名称出现在与stringifier#或令牌贴纸##的宏体参数传递给宏

之间
#define STR(x) #x 

#define STR(x) VAL(x) 
#define VAL(x) #x 
+0

如果您先定义VAL(X),该怎么办?你有相同的结果吗? – I82Much

+0

是的,与先定义STR(x)一样 – vv1133

+0

可能重复[宏扩展的确切步骤是什么?](http://stackoverflow.com/questions/6742501/whats-the-exact-step-of-macro扩展) – codaddict

回答

9

本身是宏展开,除了

在第一种情况下,STR的参数是而不是宏扩展,因此您只需获取LINE宏的名称。

在第二种情况下,STR 的说法是宏展开时,它代入VAL的定义,所以它的工作原理 - 你得到实际的行号,因为LINE宏展开。

0

C99 N1256 standard draft 6.10.3.1/1“参数替换”:

参数的函数宏的调用后已经确定, 参数替换发生。除非 之前由#或##预处理令牌或后跟##预处理令牌(请参阅下文),否则替换列表中的参数 将被替换为相应的参数,其中包含的所有宏已被 展开。在被替换之前,每个参数的预处理标记是 完全宏替换,就好像它们构成了预处理文件的其余部分一样;没有其他 预处理令牌可用。

所以###使参数被区别对待。

相关问题