Reputation: 3011
so I was playing around with recursion in C and I am not sure why is this happening:
code A
int foo(int x)
{
if (x==0) return 0;
else return foo(--x)+x;
}
int main() { printf("%d\n", foo(10));
code B
int foo(int x)
{
if (x==0) return 0;
else return foo(x--)+x;
}
int main() { printf("%d\n", foo(10));
Code A prints 45 instead of 55 and I figured that out. It is because the recursive call gets unwounded this way: 9+8+7+...+0 = 45
Code B on the other hand gets stuck and never returns to the prompt!! i have to ctrl+c
it. Why does it get stuck? Is it because it never decrements past 10?
Upvotes: 2
Views: 192
Reputation: 22979
That's because in snippet B x gets decremented after the recursive call so the function is always called with foo(10)
EDIT:
As James McNellis pointed out in its comment x gets decremented before calling the function but its original value is used in the call instead of the decremented one.
Basically the expression x-- is evaluated before foo(x--) but its value is actually x, therefore the function is called with x = 10
Upvotes: 9
Reputation: 355039
The value of the expression x--
is the current value of x
, before the stored value is decremented. So, in calling foo(x--)
, the value of the argument to foo
is always the same as its current value, yielding infinite recursion.
Note, however, that the behavior of both programs is potentially undefined, and depends on the order of evaluation of the subexpressions of foo(x--) + x
and foo(--x) + x
. Let's consider the first program, which contains the expression
foo(--x) + x
If the subexpressions are evaluated in the following (valid!) order, the program has undefined behavior:
x
is read to compute the value of the x
as the right-hand side operand of +
,
x
is read to compute the value of the x
as an operand of --
,
x
is written to store the new value of x
after it is decremented
foo
is called
The only sequence point here is between steps 3 and 4: after the argument expression is evaluated, before the function is called. Because x
is read twice (in [1] and [2]) and written once (in [3]) and because one of the reads (in [1]) is not for the purpose of computing the new value to be stored, the behavior is undefined.
Evaluation order is unspecified, but if this evaluation order is the order that is used, the program has undefined behavior.
The same reasoning applies equally to the second program.
It would be best to use x - 1
as the argument to foo
, as this expression does not modify the value of x
.
Upvotes: 1
Reputation: 4156
Post-decrement (x--)
waits for the function call to return before executing. So your stack would look like:
foo(10)
foo(10)
foo(10)
...
Upvotes: 2
Reputation:
calling
foo(--x)
calls the function with the already decremented value, while
foo(x--)
always calls it with the original value (i. e. 10), so it never gets even close to zero, that's why.
Upvotes: 0
Reputation: 1323
Yes it never decrements at all.
else return foo(x--)+x;
In the line where you call your function, you use a postdecrement, which means the value 10 is first passed to your next function and after that, it is decremented - which never happens since no function ever returns
Upvotes: 0