宏内的宏不起作用

时间:2014-05-14 18:42:28

标签: c c-preprocessor

我遇到了一段更令人困惑的代码......

#include "stdio.h"

#define f(a,b) a##b

#define g(a) #a

#define h(a) g(a)

int main(void)
{
    printf("%s\n",h(f(1,2)));
    printf("%s\n",g(1));
    printf("%s\n",g(f(1,2)));
    return 0;
}

输出

12

1

f(1,2)

我的假设是 1)由于宏f(1,2),第一个12f(a,b)取代 证实其论点 2)然后g(a)宏用字符串文字1替换"1" 3)输出应为1

但为什么g(f(1,2))没有被12取代。 我确定我在这里遗漏了一些东西。 有人能解释一下这个程序吗?

2 个答案:

答案 0 :(得分:2)

宏替换从外部发生。(严格地说,预处理器的行为就好像它一次替换一个宏,从文件的开头开始,并在每次替换后重新启动。)

标准(C99§6.10.3.2/ 2)说

  

如果在替换列表中,参数前面紧跟#预处理   令牌,两者都被单个字符串文字预处理令牌所取代   包含相应的预处理标记序列的拼写   参数。

由于#存在于宏g替换列表中,因此参数f(1,2)会立即转换为字符串,结果为{ {1}}。

另一方面,在"f(1,2)"中,由于替换列表不包含h(f(1,2)),因此适用§6.10.3.1/ 1,

  

在确定了调用类函数宏的参数之后,    参数替换发生。替换列表中的参数,除非在前面   通过##预处理令牌或后跟##预处理令牌(见下文),   在其中包含的所有宏之后用相应的参数替换   扩大。

并且参数##已展开宏以提供f(1, 2),因此结果为12,当文件被“重新扫描”时,结果变为g(12)。< / p>

答案 1 :(得分:1)

宏无法扩展到预处理指令。从C99 6.10.3.4/3“重新扫描和进一步更换”:

  

由此产生的完全宏替换的预处理标记序列   即使它类似,也不会被处理为预处理指令   一个,

来源:https://stackoverflow.com/a/2429368/2591612

但您可以像f(a,b)一样从g拨打hf(a,b)被解释为字符串文字为@Red Alert个状态。

相关问题