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



我知道我可以在GCC中使用选项-fno-optimize-sibling-calls禁用尾部递归优化。但是,它禁用了对整个编译单元的优化。

是否有一种方法可以禁用单个函数的优化?

这是我的理解,我可以改变函数,所以它不是尾部递归的有效候选者-说,通过在表达式中使用返回值,所以返回不是函数中的最后一条指令。例如:

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);
}

我正在寻找一个更干净和未来的解决方案,不需要改变算法,如果可能的话。

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

您可以使用特定于gcc的#pragma optimize()指令(结合合适的括号与push/pop#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属性应仅用于调试目的。它是

__attribute__((__optimize__("no-optimize-sibling-calls")))似乎可以在GCC上工作。

Clang给出warning: unknown attribute '__optimize__' ignored.

最新更新