内联递归函数

时间:2013-01-21 15:19:28

标签: c recursion inline

当gcc生成asm代码时,内联函数将被其代码替换。

使用内联递归函数时的行为是什么

inline int fact (int n)
{
    if (n<=1)
        return 1;
    else
        return (n * fact(n-1));
}

当递归函数带有gcc -S前缀并且递归函数没有inline前缀时,我使用inline生成asm代码,并且我发现两种情况的asm代码是一样的。

你对此有任何解释吗?

4 个答案:

答案 0 :(得分:6)

请注意,inline只是编译器可能接受或不接受的建议。它对编译器没有约束力以遵守您的建议。如果没有建议,智能编译器将内联函数。通常,对于递归函数,编译器将执行直到某些深度。

  

为什么编译器没有inline你的功能?

使用递归函数,编译器通常会寻找执行 tail call optimization 的机会。您的函数不是尾调用递归

答案 1 :(得分:4)

是:inline实际上并没有告诉编译器它必须内联函数。它唯一需要的效果是告诉链接器该函数可以在多个目标文件中定义。 (没有inline,这将是链接时错误。)

这允许您将函数定义存在于多个转换单元中,以便编译器具有内联函数的选项,而不会生成链接器错误。在决定是否内联函数时,现代编译器可能或可能不会考虑是否存在inline关键字。

答案 2 :(得分:0)

无论如何,必须编译每个内联函数,以防有人需要指向函数的指针。要检查差异,你应该使用这样的功能:

inline int fact (int n)
{
    if (n<=1)
        return 1;
    else
        return (n * fact(n-1));
}


void main () {
    printf("%d\n", fact(2));
}

答案 3 :(得分:0)

正如其他人已经说过的那样,inline仅仅是一个提示,而不是一个指示。编译器有关于内联函数的最后一句话。如果要强制内联某些内容,可以使用宏来完成。但据我所知,你不能拥有递归宏,所以这是一个死胡同。

话虽这么说,即使你可以强制内联函数,你应该知道(在任何优化级别)编译器可以将一些递归函数展开到while循环,所以你不会看到最终汇编中的任何悖论:结果循环只是内联。