0
#include <stdio.h>
#include <stdlib.h>

#define TRUE  1
#define FALSE 0

void recursion (int a) {
    if (a != 0) {
        recursion(--a); //works
        recursion(a--); //does not work
        printf("%d\n", a);
    } 
}

int main (int argc, char *argv[]) {
    printf("start\n");
    recursion(10);
    printf("finished\n");
    return 0;
}

Why is there a segmentation fault when I recurse (a--) but works fine when I recurse (--a)?

I don't think recursion(a--) is wrong due to undefined behavior because there is only one side effect, which is to decrease a by 1. This side effect is exactly what I wanted. Thanks.

Chuan
  • 429
  • 5
  • 16
  • 1
    Do you know what the difference between `--a` and `a--` is in general? Think about the actual value being passed to `recursion` on lines 7 and 8. – Ry- Oct 16 '17 at 01:31
  • `int tmp = a--; recursion(tmp);` <- how about that? – zerkms Oct 16 '17 at 01:34
  • `recursion(a--);` calls `recursion(a);` every time then decrease a but then the decreased value isn't used anymore – phuclv Oct 16 '17 at 01:34
  • @zerkms that would be identical to the actual code – M.M Oct 16 '17 at 02:39
  • @M.M exactly. But it would give OP another hint on why it happens (since they started digging too deep thinking of sequence points and number of side effects). – zerkms Oct 16 '17 at 03:10

1 Answers1

2

Both --a and a-- have the side effect of incrementing a. The difference is that the value of the expression --a is the value of a after decrementing, while the value of a-- is the value of a before decrementing.

So in the latter case the same value of a is passed recursively to the function. As a result, you have an infinite recursive loop which causes a stack overflow.

You need to use recursion(--a) for the recursive call in order for the decremented value of a to be passed to the function.

dbush
  • 205,898
  • 23
  • 218
  • 273
  • why is this so? why a-- is the value of a before decrementing? I cannot find an explanation. In terms of precedence a-- and --a all will be carried out first before the function call since they are must binding. – Chuan Oct 16 '17 at 06:32
  • 1
    @ChuanyuanLiu In either case `a` will always be updated before the function is called. The difference is that the _expressions_ evaluate differently, so the value passed to the function in the `a--` case is not the same as the value of `a` after executing that line of code. – Lundin Oct 16 '17 at 09:48