我知道我可以使用-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); }
如果可能的话,我正在寻找一种更干净、更适合未来的解决方案,它不需要改变算法。
浏览文档时,我找不到能做到这一点的函数属性或内置函数,但我的搜索并不是详尽的。
发布于 2021-09-25 10:03:23
您也许能够使用特定于GCC的函数指令(combined with suitable bracketing with push/pop #pragma
lines)来实现类似于指定#pragma optimize()
属性的结果:
#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
。另外,请注意此警告from the manual
并不是每个以属性指定的-f前缀开头的优化选项都会对函数产生影响。optimize属性应仅用于调试目的。它不适用于生产代码。
发布于 2021-09-25 09:23:01
__attribute__((__optimize__("no-optimize-sibling-calls")))
似乎对GCC起了作用。
Clang给了warning: unknown attribute '__optimize__' ignored
。
https://stackoverflow.com/questions/69328139
复制