Is it possible to write a recursive static function in C?
Yes, it most certainly is. When you apply static
to a function, it's not the same as a static variable within a recursive function (which is a problem if it's used in the calculations).
When applied to a function (or an object outside of a function), static
simply controls whether that thing is visible outside the compilation unit (for the linker, for example).
When applied to an object within a function, static
means that the variable exists beyond the duration of the function. In the context of a recursive function, it also means that there is only one copy of the variable for all recursion levels rather than one per recursion level, which is usually what's needed.
So this (what your question appears to be asking about) is perfectly okay:
static unsigned int fact (unsigned int n) {
if (n == 1U) return 1;
return n * fact (n-1);
}
This, on the other foot, is not okay, since the single copy of the static variable will probably be corrupted by the lower recursive layers.
static unsigned int fact (unsigned int n) {
static unsigned int local_n;
local_n = n;
if (local_n == 1U) return 1;
return fact (local_n - 1) * local_n;
}
In more detail, consider a call to fact(3)
:
local_n
is set to 3
, then a call is made to fact(2)
.local_n
is set to 2
, and a call is made to fact(1)
.local_n
is set to 1
, and we just return 1
because that's the base case of the recursion.That's when things seem to start going wrong (although, technically, they started going wrong as soon as we typed in that static
keyword for the local_n
declarator):
1
and multiply it by local_n
. Now, had that variable not been static, it would have the (local) value of 2
. Unfortunately, it is static, so was set to 1
in the previous step. Hence we return 1 * 1
or, ... hang on, let me check this on the calculator ..., 1
:-)1
and multiply it by local_n
which, of course, still has the value 1
. So we again multiply 1 * 1
and return 1
.If you want to try it out, here's a complete program:
#include <stdio.h>
static unsigned int fact (unsigned int n) {
static unsigned int local_n; // bad idea!
local_n = n;
if (local_n == 1U) return 1;
return fact (local_n - 1) * local_n;
}
int main() {
printf("%d\n", fact(3));
return 0;
}
That outputs the erroneous 1
but, if you get rid of the static
keyword in the local_n
declarator, it will return the correct 6
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With