0

I am playing around with some recursion, and trying to count the number of additions in a recursive fib function (code below). The problem is, g_add never gets printed as anything but zero (0). In the debugger it is set correctly, but it wont print correctly. In fact, the code below is modified a bit, to sanity check that everything else is OK. In real life, g_add is set to zero initially, not to the 10 below, but look at the output is printing...

volatile int g_add = 10;
int rfib(int n)
{
    if(n == 0)  return 0;
    else if(n == 1) return 1;
    else {
        ++g_add;
        return rfib(n-1) + rfib(n-2);
    }
}

int _tmain(int argc, _TCHAR* argv[])
{

    printf("Fib: %d\n", g_add);
    for(int n =0; n<6;n++,g_add = 0)
    {
        printf("Fib %d is: %d - additions: %d\n", n, rfib(n), g_add);
    }
}

And the output:

Fib: 10
Fib 0 is: 0 - additions: 10
Fib 1 is: 1 - additions: 0 
Fib 2 is: 1 - additions: 0
Fib 3 is: 2 - additions: 0 (note, the debugger says it is 1)
Fib 4 is: 3 - additions: 0
Fib 5 is: 5 - additions: 0

Any thoughts on why g_add is not being printed correctly? And what I could do about it? I have tried with and without the volatile keyword. I think this might be related to the VS environment, rather than C++ so, I tagged both.

teleball
  • 4,602
  • 6
  • 37
  • 38
  • 1
    Function operands evaluation order is not specified by the standards i.e it is left to the compiler to decide the order of evaluation. – Khaled Alshaya Sep 01 '09 at 22:36

2 Answers2

6

You're assuming the order in which the parameters are evaluated.

Use this instead:

int fib = rfib(n);
printf("Fib %d is: %d - additions: %d\n", n, fib, g_add);
gatorfax
  • 1,124
  • 2
  • 7
  • 13
  • Exactly the answer I was posting. +1 – Fred Larson Sep 01 '09 at 22:33
  • Parameters are evaluated right to left unless you declare the function using the `__stdcall` calling convention, as far as I know. – isekaijin Sep 01 '09 at 22:38
  • @ Eduardo León: The order is not specified in the standard (delibrately). Thus compiers are free to evaluate them in any order. __stdcall on the other hand affects the ABI and just specifies what order they are pushed onto the stack, it has no affect on the order of evaluation. – Martin York Sep 01 '09 at 22:43
1

Order of evaluation of parameters to a function is not specified in the standard.
This compilers are allowed to do appropraite optimisations.

See: What are all the common undefined behaviours that a C++ programmer should know about?

In your situation.

  • It is evaluating the fourth argument (g_add)
  • Before the third argument (rfib(n))
Community
  • 1
  • 1
Martin York
  • 257,169
  • 86
  • 333
  • 562