【问题标题】:Will a modern compiler such as GCC perform a tail case optimization in such cases? [duplicate]在这种情况下,诸如 GCC 之类的现代编译器会执行尾部优化吗? [复制]
【发布时间】:2017-08-01 14:55:11
【问题描述】:

假设我有这样的功能:

int recursivefunction (int n) {
    if (n>10) return n; /* terminal case */
    elseif (n>5) return n*recursivefunction(n-1); /* non tail call*/
    else return recursivefunction(n-1); /* tail call

第三次递归调用会被优化为尾调用吗?如果不是为什么不呢? 我们可以用一个清除当前函数堆栈帧的汇编代码替换第三个返回语句,除了传递给下一个调用的局部变量,以及指向函数地址的 goto,这样就不会保留堆栈上的空间。

【问题讨论】:

  • -O2 -fdump-tree-optimized编译,查看生成的file.c.226t.optimized(数字可能随gcc版本变化)...

标签: c++ c gcc


【解决方案1】:

可能,但不能保证。

如果 n 小于或等于 5,则代码并不是一个无限循环,但在计算 INT_MIN-1 时最终的下溢是未定义行为。如果编译器发现了这一点,它可以做任何事情,包括返回 42 或其他一些无法指定的值,而根本不做任何调用。第二个递归调用也是如此,因为它很快就会落入第三个。

简而言之,如果参数值小于或等于 10,则对编译器没有任何限制,因为任何这些情况最终都会执行行为未定义的计算。因此编译器有权假设程序员将确保仅使用大于 10 的参数调用该函数。如果是这种情况,该函数只是恒等函数,因此编译器可能会删除所有递归调用,尾部位置与否。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-30
    • 1970-01-01
    • 2018-04-06
    • 1970-01-01
    相关资源
    最近更新 更多