C预处理器将标识符视为对象而不是类似函数

Eya*_*yal 2 c macros c-preprocessor

这是我刚刚在工作中遇到的一些代码的简化版本:

#include <stdio.h>

#define F(G) G(1)
#define G(x) x+1

int main() {
  printf("%d\n", F(G));
}
Run Code Online (Sandbox Code Playgroud)

打印2.

现在,我可以看到F(G)扩展到G(1)然后G(1)扩展到2,但我不清楚为什么.我本来期望得到一个错误,G不是printf行的函数.

预处理器如何解析这样的代码?

Jam*_*lis 6

只有在其名称后跟a时,才会调用类似函数的宏(.

F(G),G后面没有a (,所以G没有宏调用.

F(G) G(1),G是一个宏参数,因此不直接宏替换(这是一个非常令人困惑的宏:-O).In G(1),G由对应于参数的参数替换,该参数G也恰好是G.然后重新扫描该替换并G(1)进行评估1 + 1.

如果我们重写您的宏以便您不会G以多种不同的方式使用它,那么理解起来要容易得多:

#define F(x) x(1)
#define G(x) x + 1
Run Code Online (Sandbox Code Playgroud)

在这里,F(G)被替换为G(1).然后重新扫描,然后G评估调用,产生1 + 1.