Would it be a true statement to say that every recursive function needs to be reentrant?
-
Retagged as possible homework. – ivans Jun 16 '10 at 10:24
-
Not homework, just a question I had. Not at school anymore; at work – Tony The Lion Jun 16 '10 at 10:25
-
Retagged: recrusion => recursion – pakore Jun 16 '10 at 13:31
4 Answers
If by reentrant you mean that a further call to the function may begin before a previous one has ended, then yes, all recursive functions happen to be reentrant, because recursion implies reentrance in that sense.
However, "reentrant" is sometimes used as a synonym for "thread safe", which is introduces a lot of other requirements, and in that sense, the answer is no. In single-threaded recursion, we have the special case that only one "instance" of the function will be executing at a time, because the "idle" instances on the stack are each waiting for their "child" instance to return.

- 114,894
- 38
- 205
- 284
-
4Reentrant and thread-safe are not the same thing: http://en.wikipedia.org/wiki/Reentrant_(subroutine) – Hawkeye Parker Aug 06 '14 at 22:23
-
"reentrancy" usually has a wider meaning that the previous execution of the function may be interrupted at **any time** and in this state a new call to the same function can be performed. So the new execution of the function can be induced by an external asynchronous event (interrupt) at any time not just by a pre-defined recursive call or callback. – pabouk - Ukraine stay strong Aug 05 '21 at 13:17
No, I recall a factorial function that works with static (global) variables. Having static (global) variables goes against being reentrant, and still the function is recursive.
global i;
factorial()
{ if i == 0 return 1;
else { i = i -1; return i*factorial();
}
This function is recursive and it's non-reentrant.

- 11,395
- 12
- 43
- 62
Not at all.
Why shouldn't a recursive function be able to have static data, for example? Should it not be able to lock on critical sections?
Consider:
sem_t mutex;
int calls = 0;
int fib(int n)
{
down(mutex); // lock for critical section - not reentrant per def.
calls++; // global varible - not reentrant per def.
up(mutex);
if (n==1 || n==0)
return 1;
else
return fib(n-1) + fib(n-2);
}
This does not go to say that writing a recursive and reentrant function is easy, neither that it is a common pattern, nor that it is recommended in any way. But it is possible.

- 161,610
- 92
- 305
- 395
-
-
Daniel: It's against the definition: http://en.wikipedia.org/wiki/Reentrant_%28subroutine%29 unless, you have a different one. – Noon Silk Jun 16 '10 at 10:25
-
1That page is ridiculous (check the discussion page). Consider the APIs for accessing a file system - they access shared global data and yet can be called simultaneously from multiple threads/processes. – Daniel Earwicker Jun 16 '10 at 10:32
-
Adding a mutex doesn't make that reentrable: one thread will return the wrong result, if another thread is still using/inside the function. – ChrisW Jun 16 '10 at 10:35
-
If a file system is thread-safe because it uses locks to protect static data, then that's because those of its subroutines which access static data aren't themselves reentrable (which is why they need the protection). – ChrisW Jun 16 '10 at 10:38
'Reentrant' normally means that the function can be entered more than once, simultaneously, by two different threads.
To be reentrant, it has to do things like protect/lock access to static state.
A recursive function (on the other hand) doesn't need to protect/lock access to static state, because it's only executing one statement at a time.
So: no.

- 54,973
- 13
- 116
- 224
-
2It is possible to have a thread-safe, but not reentrant function (even for a single-threaded application). In fact there's an example in http://en.wikipedia.org/wiki/Reentrancy_(computing) – sashoalm Apr 03 '14 at 11:58