GCC/Clang:禁用单个函数的尾递归优化

问题描述 投票:0回答:2

我知道我可以使用选项

-fno-optimize-sibling-calls
在 GCC 中禁用尾递归优化。但是,它禁用了整个编译单元的优化。

有没有办法禁用单个功能的优化?

据我所知,我可以更改函数,使其不是尾递归的有效候选者 - 例如,通过在表达式中使用返回值,因此返回不是函数中的最后一条指令。例如:

return f(n) + 1;

上面的解决方案可能仍然是可优化的,并且编译器的未来(或当前,我不知道)版本可能足够聪明,可以将其变成尾调用 - 比如说,通过改变

int f(i) {
  if(!i) return 0;
  return f(i - 1) + 1;
}

进入

int f(i, r = 0) {
  if(!i) return r;
  return f(i - 1, r + 1);
}

我正在寻找一种更简洁、面向未来的解决方案,如果可能的话,它不需要更改算法。

查看文档我找不到函数属性或内置函数,但我的搜索并不详尽。

c++ gcc optimization clang tail-recursion
2个回答
1
投票

您可以使用特定于 GCC 的

#pragma optimize()
指令(结合适当的括号与推送/弹出
#pragma
)来实现类似于指定函数属性的结果:

#pragma GCC push_options // Save current options
#pragma GCC optimize ("no-optimize-sibling-calls")
int test(int i)
{
    if (i == 1) return 0;
    return i + test(i - 1);
}
#pragma GCC pop_options  // Restore saved options

int main()
{
    int i = 5;
    int j = test(i);
    return j;
}

但请注意,clang 不支持这种形式的

#pragma optimize
。另外,请注意手册中的警告

不是每个以指定的 -f 前缀开头的优化选项 属性必然会对功能产生影响。这 optimize 属性应该仅用于调试目的。这是 不适合生产代码。


0
投票

__attribute__((__optimize__("no-optimize-sibling-calls")))
似乎适用于 GCC。

Clang 给

warning: unknown attribute '__optimize__' ignored
.

© www.soinside.com 2019 - 2024. All rights reserved.