Akshat Jain
Akshat Jain

Reputation: 111

How is the "static" keyword affecting the calculation?

I have an issue in this code, using the static keyword. Here, after n = 3, I thought the value of r will be 5, but I found out that the value of r is 50! I don't know how static works here:

int magic(int n)
{
    static int r = 5;
    if (n <= 0) return 10;

    if (n > 3)
    {
        r = 50;
        return(r + magic(n-1));
    }
    return(r - magic(n-1));
}

int main()
{
    int x;
    x = magic(8);
    printf("%d",x);
}

Here output is 290, because r has a value of 50 in all cases. Please can someone help me in this.

Upvotes: 0

Views: 91

Answers (1)

Adrian Mole
Adrian Mole

Reputation: 51815

When you have the statement, static int r = 5;, this signals to the compiler that the variable r will be initialised to the value 5 at compile time. That means, it will not be reset to 5 each time the function is called!

Also, the line if (r > 3) doesn't work as you suggest (see my comment in your question)! Changing to if (n > 3) does what you say.

Anyway, the following code does something different (outputs 245), but I'm not sure what you expect the output to be:

#include <stdio.h>

int magic(int n)
{
    int r = 5; // NOT STATIC - so this is reset to 5 at the start of each call!
    if (n <= 0) return 10;
    else if (n > 3) { // Your "if (r > 3)" means the block will ALWAYS execute!
        r = 50;
        return(r + magic(n - 1));
    }
    return(r - magic(n - 1));
}

EDIT: I shall try to add some clarification! Consider a statement that declares and initialises a static variable in the 'global' scope (that is, not inside any function, or even in main):

static int StatInt1 = 42;

When the compiler encounters this statement, it 'allocates' a part of memory for the program, large enough to hold an int and gives that piece of memory the value that represents 42. The compiler does not generate any machine code instruction for moving the value given into that memory; in fact, it cannot possibly generate such code - for there is no 'context' in which to run that code.

However, if you later (somewhere in a function, or in main) have a statement like this:

StatInt1 = 9;

then the compiler will generate code that moves the representation of the value 9 into the memory previously 'allocated' for the variable. Exactly what this code will be depends on the compiler and target machine, but let's say it is an instruction MOVE 9 TO @StatInt1 (where @StatInt1 is the address of the 'allocated' memory block).

Now, if you were to move the static int StatInt1 = 42; statement into the body of a function (much like you have), this (by definition) does not change the way the compiler interprets the statement! All it does is make access to the variable 'local' to that function. There is still no code generated to move the value into the variable!

But a variable inside a function that is not declared static is treated very differently - we sometimes refer to such variables as 'automatic'! The memory block for such a variable is only 'allocated' when the function is actually invoked, and then it will be assigned the value given in the initialiser each time the function is called. (Typically, most compilers will create the memory on the stack: short-term memory that is 'wiped out' when the function ends.)

In your code, the static int r = 5; does not generate any code, so there is no 'automatic' re-assignment of the value 5 when the function is called. Thus, once the function has been called in such a way as to assign the value 50 to r, it will keep that value until you explicitly give it another value.

I apologise if this is rambling - but I hope it makes it clear(er) what is going on!

Upvotes: 2

Related Questions