我最近阅读了几个声明为static
的递归函数。
在函数声明前添加static
是否有助于GCC优化尾递归函数?这是否必须得到优化?
答案 0 :(得分:8)
我没有看到任何函数static
应该帮助编译器优化递归调用的原因。
立即,您看到的递归函数更可能只是编译单元的内部函数。递归函数经常需要一个比想要暴露给程序其余部分更丰富的接口 - 例如,可能有额外的参数仅由递归调用使用,或者返回值来自可能需要调整一般调用以适应想要呈现给代码的其余部分的抽象。因此,通常编写一个包装函数来设置额外参数的默认值,并且通常将递归函数的接口调整为外部有意义的好东西。
现在由于递归函数只能由它自己和包装器函数调用,所以很自然地声明它static
- 不是因为递归本身,而是为了防止用它来污染全局命名空间。编译器也可以使用更有效的调用约定(适用于特定的函数体)用于静态函数,因为它知道所有的调用站点,并且不必遵循允许单独编译的代码调用它的ABI。
答案 1 :(得分:3)
不,static
与任何递归优化无关。当函数声明为static
时,它会获得内部链接,因此除了来自同一翻译单元中的其他函数之外,它不能被调用/使用。
答案 2 :(得分:1)
静态(即内部链接)对函数的一个影响是它告诉编译器直接调用到给定函数的所有可能用例都被本地化在当前转换单元中。这可能确实会对某些优化产生影响。例如,如果编译器决定在转换单元中内联所有对给定函数的调用(并且没有采用该函数的地址),则它立即知道该函数不需要独立的主体。或者,另一个例子,如果总是以1
作为参数调用函数,那么从技术上讲,这个参数可以完全消除。等等。
使用外部链接功能,这样的优化也是可能的,但需要有关整个程序的全局知识(这就是为什么它们通常被称为全局优化)。通过内部链接功能,所有这些功能都可以在一个翻译单元中打开。
但是,对于尾部递归消除这样的优化,它应该无关紧要。