No, there is no way to tell a compiler that tail recursion is required. Some compilers (none that I'm aware of) may support implementation-specific annotations, but that requires the user to use that specific compiler. Some other compilers, in some modes, intentionally never support tail calls, because they can provide a better debugging experience by not supporting tail calls. The user may be using such a compiler.
The allowed recursion depth is highly program-, function- and implementation-dependent, and no sensible numbers can be given for it. Given a specific platform, you can probably determine the default stack size, investigate the frame size for one particular compiler on that platform, and do a simple division to get a rough estimate of how many nested calls you can have.
I recommend rewriting it in a way that makes it clear to the reader what is happening, but does not rely on a compiler optimising tail calls. Although hated, the goto
statement can be very useful for this.
Take a simple tail-recursive bit-counting function:
int bitcount(unsigned int n, int acc = 0) {
if (n == 0)
return acc;
return bitcount(n >> 1, acc + (n & 1));
}
It can be trivially rewritten as
int bitcount(unsigned int n, int acc = 0) {
tail_recurse:
if (n == 0)
return acc;
// tail return bitcount(n >> 1, acc + (n & 1));
acc += n & 1;
n = n >> 1;
goto tail_recurse;
}
Of course this is a simple version that is trivially rewritten to avoid recursion entirely, and probably shouldn't even be implemented manually, but the specific transformation I've used here is one that you can apply to any function where tail recursion is possible and where you need tail recursion. The comment should make sure that the reader can still easily spot what's going on.