为什么在C中按正常顺序评估类似函数的宏?

时间:2015-12-12 00:51:08

标签: c macros

下面给出的C程序:

#define p(x) (printf("%d ", x))
#define q(a,b,c) ({int total = a; printf("%d ", b); total += c;})
int main(){
    q(p(1), 2, p(3));
}

生成输出1 2 3,表明使用了正态订单评估。但是,对于正常功能,例如此代码段:

int p(int i){
    printf("%d ", i);
    return i;
}

void q(int a, int b, int c){
    int total = a;
    printf("%d ", b);
    total += c;
}
int main(){
    q(p(1), 2, p(3));
}

输出为1 3 2,表示使用了应用订单评估。这种行为的根本基础是什么?与函数相比,宏的参数如何评估?

1 个答案:

答案 0 :(得分:3)

宏评论在评估之前完全展开,因此编译器将按p,p,q的顺序评估宏。但是,代码实际上并未在此阶段执行,只是作为文本扩展。

所以你的第一个例子将扩展为:

int main() {
    ({int total = (printf("%d", 1); printf("%d", 2); total += printf("%d", 3);});
}

然后根据正常的c规则将其编译为一系列语句。

对于函数,编译器分别为每个函数生成代码,然后将调用放在它们使用的位置。这意味着它必须知道q的参数值,然后才能调用q。