为什么类函数宏在 C 语言中以正常顺序求值?
Why are function-like macros evaluated in Normal-Order in C?
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
,这意味着使用了应用顺序评估。这种行为的潜在基础是什么?与函数相比,宏的参数如何求值?
宏参数在计算之前被完全展开,因此编译器将按照 p、p、q 的顺序计算宏。然而代码并没有在这个阶段实际执行,只是扩展为文本。
因此您的第一个示例将扩展为:
int main() {
({int total = (printf("%d", 1); printf("%d", 2); total += printf("%d", 3);});
}
然后根据正常的 c 规则将其编译为语句序列。
对于函数,编译器分别为每个函数生成代码,然后将调用放在使用它们的地方。这意味着它必须知道 q 的参数值,然后才能调用 q。
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
,这意味着使用了应用顺序评估。这种行为的潜在基础是什么?与函数相比,宏的参数如何求值?
宏参数在计算之前被完全展开,因此编译器将按照 p、p、q 的顺序计算宏。然而代码并没有在这个阶段实际执行,只是扩展为文本。
因此您的第一个示例将扩展为:
int main() {
({int total = (printf("%d", 1); printf("%d", 2); total += printf("%d", 3);});
}
然后根据正常的 c 规则将其编译为语句序列。
对于函数,编译器分别为每个函数生成代码,然后将调用放在使用它们的地方。这意味着它必须知道 q 的参数值,然后才能调用 q。