Search code examples
javac++recursionoperator-precedenceconsole-output

Different results in Java and C++ using += in recursion


The very simple Java code as follows has the weird output, but the same logic code in C and C++ has the right output. I try with the JDK 1.7 and JDK 1.3 (relative JRE), the weird output is always there.

public class Test {

    public static int sum=0;

    public static int fun(int n) {

        if (n == 1)
            return 1;
        else
            sum += fun(n - 1);  // this statement leads to weird output
        // { // the following block has right output
        //     int tmp = fun(n - 1);
        //     sum += tmp;
        // }

        return sum;
    }

    public static void main(String[] arg) {
        System.out.print(fun(5));
    }
}

The output is 1 which should be 8. Relative C/C++ code is as follows:

#include<stdio.h>
int sum=0;
int fun(int n) {

        if (n == 1)
            return 1;
        else
            sum += fun(n - 1);

        return sum;
    }

int main()
{
    printf("%d",fun(5));

    return 0;
}

Adding test java code:

class A {
    public int sum = 0;

    public int fun(int n) {
        if(n == 1) {
            return 1;
        } else {
            sum += fun(n - 1);
            return sum;
        }
    }
}

public class Test {
    public static void main(String arg[]){
        A a = new A();
        System.out.print(a.fun(5));
    }
}

Solution

  • I'm going to run through this for fun(3) for the sake of giving a complete answer. For those of you who are not interested why this works for C++ but not for Java, please ignore my answer.

    Here is what Java is doing:

    inside fun(3)

    sum += sum + fn(n-1) // sum is 0
    

    becomes

    sum = 0 + fun(2) // sum is 0
    

    Then inside fun(2)

    sum = 0 + fun(1) // sum is 0
    

    Then inside fun(1)

    return 1 // sum is 0
    

    Back inside fun(2)

    sum = 0 + 1; // sum is 0
    

    becomes

    sum = 1; // sum will soon become 1
    

    Back inside fun(3)

    sum = 0 + 1; // sum is 1
    

    becomes

    sum = 1; // sum gets reset to 1
    

    Here is what C++ is doing:

    inside fun(3)

    sum += fn(n-1) // sum is 0
    

    becomes

    sum = sum + fn(2) // sum is 0
    

    Then inside fun(2)

    sum = sum + fn(1) // sum is 0
    

    Then inside fun(1)

    return 1 // sum is 0
    

    Back inside fun(2)

    sum = sum + 1 // sum is 0
    

    Becomes

    sum = 0 + 1 => sum = 1 // sum will soon become 1
    

    Back inside fun(3)

    sum = sum + 1 // sum is 1
    

    Becomes

    sum = 1 + 1 // sum will soon become 2
    

    What you should do: I do not know why C++ evaluates sum after making the function call rather than before. I do not know if this is in the specifications. But I do know that you should not be depending on this in any language. A correct solution would be:

    int fun(int n) {
        if (n == 1)
            return 1;
        else
            return n + f(n - 1);
    }