"sibling calls"是什么意思?

What does "sibling calls" mean?

本文关键字:意思 calls sibling 是什么      更新时间:2023-10-16

在GCC手册上,

-优化同级调用

优化同级和尾部递归调用。

我知道尾部递归调用,例如

int sum(int n){return n==1?1:n+sum(n-1);}

但是,兄弟调用是什么意思?

尾调用

如果一个函数调用是在另一个函数中执行的最后一个操作,则称其为尾部调用。

这个名称源于这样一个事实,即函数调用出现在其他函数的尾部位置。

int foo(int a, int b) {
// some code ...
return bar(b);    // Tail call which is neither sibling call nor tail recursive call.
}

CCD_ 1出现在CCD_ 2的尾部位置。对bar的调用是尾部调用。


尾部递归调用

尾部递归调用是尾部调用的一种特殊情况,其中被调用者函数和调用者函数相同。

int foo(int a, int b) {
if (a > 0) {
return foo(a - 1, b + 1);    // Tail recursive call
} else {
return b;
}
}

同级呼叫

同级调用是尾部调用的另一种特殊情况,其中调用方函数和被调用方函数不需要相同,但它们具有兼容的堆栈占用。

这意味着两个函数的返回类型必须相同,并且传递的参数必须占用相同的堆栈空间。

int foo(int a, int b) {
// some code ...
return bar(a - 1, b);    // Sibling call, also a tail call, but not a tail recursive call.
}

每个尾部递归调用都是同级调用,因为定义意味着每个函数都是其自身的同级调用。


为什么与众不同

由于相同的堆栈占地面积,更换堆栈框架变得相对容易。编译器编写者不必调整堆栈框架的大小,并且就地突变变得很简单。

编译器如果两个函数共享,则将其视为兄弟函数返回类型的结构等价,以及匹配空间他们论点的要求。

http://www.drdobbs.com/tackling-c-tail-calls/184401756

它一定是这样的:

int ispair(int n) { return n == 0 ? 1 : isodd(n-1); }
int isodd(int n) { return n == 0 ? 0 : ispair(n-1); }

一般来说,如果函数调用是最后一句话,那么它可以用跳转来代替。

void x() { ......; y(); }

在这种情况下,y()可以用跳转(或内联函数)代替,而不是使用标准函数调用。