I understand I can disable tail recursion optimization in GCC with the option -fno-optimize-sibling-calls
. However, it disables the optimization for the whole compilation unit.
Is there a way to disable the optimization for a single function?
It is my understanding that I can change the function so it's not a valid candidate for tail recursion - say, by using the return value in an expression so the return is not the last instruction in the function (e.g.: return f(n) 1;
).
The solution above may still be optimizable, though, and future (or current, I don't know) versions of the compiler may be smart enough to make it into a tail call - say, by changing int f(i) { if(!i) return 0; return f(i - 1) 1; }
into int f(i, r = 0) { if(!i) return r; return f(i - 1, r 1); }
I'm looking for a cleaner and future proof solution that doesn't require changing the algorithm, if at all possible.
Looking through the documentation I couldn't find a function attribute or built-in that does that, but my search hasn't been exhaustive.
CodePudding user response:
__attribute__((__optimize__("no-optimize-sibling-calls")))
appears to work on GCC.
Clang gives warning: unknown attribute '__optimize__' ignored
.
CodePudding user response:
You may be able to use the GCC-specific #pragma optimize()
directive (combined with suitable bracketing with push/pop #pragma
lines) to achieve a result similar to specifying a function attribute:
#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;
}
But note that clang doesn't support this form of #pragma optimize
. Also, note this warning from the manual:
Not every optimization option that starts with the -f prefix specified by the attribute necessarily has an effect on the function. The optimize attribute should be used for debugging purposes only. It is not suitable in production code.