I have a recursive function that I would like to make tail-recursive. My actual problem is more complex and context-dependent. But the issue I would like to solve is demonstrated with this simple program:
#include <iostream>
struct obj
{
int n;
operator int&() { return n; }
};
int tail(obj n)
{
return tail(obj{ n + 1 > 1000 ? n - 1000 : n + 1 });
}
int main()
{
tail(obj{ 1 });
}
It seems natural that this is tail-recursive. It is not, though, because the destructor of obj n
has to be called each time. At least MSVC13 (edit:) and MSVC15 do not optimize this. If I replace obj
with int and change the calls accordingly, it becomes tail-recursive as expected.
My actual question is: Is there an easy way to make this tail-recursive apart from just replacing obj
with int
? I am aiming for performance benefits, so playing around with heap-allocated memory and new
is most likely not helpful.
Since you use a temporary, I assume you don't need the object after the recursive call.
One fairly hackish solution is to allocate an object, pass a pointer to it, and reallocate it before making the recursive call, to which you pass the object you newly constructed.
I've obviously omitted some crucial exception safety details. However GCC is able to turn
tail_impl
into a loop, since it is indeed tail recursion.