0
#include <stdio.h>
int sum(int a);
int main()
{
   int a;
   printf("Enter a value: ");
   scanf("%d", &a);
   printf("%d", sum(a));
   return 0;
}
int sum(int a)
{
   if (a == 1)
   {
      return 1;
   }
   return a + sum(a - 1);
}

When the input is 5 the output is 15 (which is right), but when the return is, return a + sum(--a); (for the same input 5) the output is 11

734
  • 1
  • 1
  • 3
    Because `a + sum(--a)` is [*undefined*](https://stackoverflow.com/questions/949433). It's impossible to know whether you get the old or the new value of `a` on the left-hand-side of the `+` sign. (That is, you can't tell if you get `old_a + sum(--a)` or `new_a + sum(--a)`.) – Steve Summit Aug 02 '22 at 15:11
  • See also [this question](https://stackoverflow.com/questions/68024823) and [this answer](https://stackoverflow.com/questions/68024823#68024993). – Steve Summit Aug 02 '22 at 15:16
  • The bottom line is that since `a + sum(a - 1)` is clear and concise and does what you want, that's the form you should use. The `++` and `--` operators are more powerful but at least a little bit harder to think about, and they do more (much more!) than just `a + 1` or `a - 1`, so you should only use the `++` and `--` operators when you (a) know what you're doing and (b) truly need their extra power. – Steve Summit Aug 02 '22 at 15:18

2 Answers2

2

The behaviour of a + sum(--a) is undefined. The compiler has a lot of freedom as to when and how often it reads a, and when and how often it modifies a. Avoid both reading and modifying the same variable in an expression.

ikegami
  • 367,544
  • 15
  • 269
  • 518
0

When you wrote

a + sum(a - 1)

, a rough translation of that C code into English is:

"Take a plus the result of the sum function applied to the quantity a-1."

That makes sense, and it's just what you want.

If, on the other hand, you write

  a + sum(--a)

, now what you're saying is,

"Take a plus the result of the sum function applied to, hang on a minute, I want to take the variable a minus 1 and assign it back to a and then, where was I, pass it to sum()."

Is that really what you want to do? Why would you want to modify a's value in the middle of calling sum()? You wouldn't want to do that, you don't need to do that, that has nothing to do with the problem of calling sum(a - 1). So don't write it that way. It's confusing to you and me, and what's worse, it's so confusing that the compiler can't figure it out, either. It's so confusing that it's undefined behavior, meaning that the compiler isn't even required to figure out what you mean, and the compiler is explicitly allowed to fall back and punt, and compile your program into something that doesn't work — which is precisely what you discovered when you tried it.

See the canonical SO question Why are these constructs using pre and post-increment undefined behavior? for much (much!) more on undefined expressions like these.

Steve Summit
  • 45,437
  • 7
  • 70
  • 103