4

Below is my code:

//main.c

int f()
{
    static int x = 0;
    x += 1;
    return x;
}

int main()
{
   f();
   printf("%d", f());
}

and the output is 2.

I know that static variable will persist state, but since I called f() twice, each time x is set to 0 first (static int x = 0; ), then plus 1, then the output should be 1 regardless of how many times I call f()?

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • 4
    **Before answering**: consider there are already 8 answers to this question and the topic is fairly basic. Does your answer add something new or improves in a significant way something already said ? – bolov Aug 26 '20 at 14:23

5 Answers5

6

static variables not only persist, they are initialized once only, so x is not "each time set to 0 first", it remains 1 in the second call and then gets incremented. So indeed

static int x = 0;  // x is initialized once only

is very different from

static int x;
x = 0; // x is set to 0 with every call
ryyker
  • 22,849
  • 3
  • 43
  • 87
Ingo Leonhardt
  • 9,435
  • 2
  • 24
  • 33
2

each time x is set to 0

No, you are reading the code incorrecly. The = here does not indicate assignment, rather it indicates initialization because its part of a declaration. The initial value of the variable is specified explicitly to 0. Static variables are only initialized once during a program's execution. If their declaration appears inside a function it doesn't change that behavior.

Also, an initializer for a static variable must be a constant expression (an expression that can be evaluated at compile time to a known value). This means that practically, an implementation doesn't need to introduce code to do any initialization inside the function. The value can be simply loaded into the storage of the variable at program startup.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

You made two calls to f(), x has static storage duration, its lifetime is the entire execution of the program. This is why 2 is printed and not 1.

Tony Tannous
  • 14,154
  • 10
  • 50
  • 86
0

"...but since I called f() twice, each time x is set to 0 first (static int x = 0;),..."

No. x is not set to 0 each time f is called.

static variables are initialized only once at the first call to the function in which they are defined.

The special thing in comparison to automatic variables is that the memory object allocated persists until the end of the program.

The object as well as the value of x stays the same between different calls to the function f. So x is incremented by one at each call to the function without a reset to the once initialized value.

// Calls to f() in order
f();         // value of x at the end of the function: 1
f();         // value of x at the end of the function: 2
f();         // value of x at the end of the function: 3
f();         // value of x at the end of the function: 4
// and so on.

So, when you call f() twice, 2 is the correct value of x at the moment the function returns.


Side notes:

  • The explicit initialization of 0 is redundant. static variables are initialized to 0 by default.

  • The parameter list definition/declaration of a function in C should not be left omitted. Instead of int f(), write int f(void). int main() also should be edited to int main (void). int main() is obsolete.

  • It's good to use the `int main(void)` notation, but note that the C11 standard (Example 3 in [§6.5.3.4 The `sizeof` and `_Alignof` operators](http://port70.net/~nsz/c/c11/n1570.html#6.5.3.4p8)) shows `int main() { … }`. Granted, it is not normative because it is an example, but…. – Jonathan Leffler Aug 26 '20 at 14:53
  • @JonathanLeffler Yes, I know. I found these examples too and wondered about. I had a [conversation with Keith](https://stackoverflow.com/questions/29190986/is-int-main-without-void-valid-and-portable-in-iso-c/29190987#comment110667781_29190987) going on about this case and the conclusion was to better use the `int main (void)` form. Hence the recommendation. – RobertS supports Monica Cellio Aug 26 '20 at 15:05
  • I 100% agree ”better”. I'm cavilling about ”standard-compliant”. It is compliant code but not beat modern practice. – Jonathan Leffler Aug 26 '20 at 15:19
  • 1
    @JonathanLeffler What about Keith's reasoning for guaranteed compliance with future standards (in case the committee remove that ambiguity)? – RobertS supports Monica Cellio Aug 26 '20 at 15:22
  • There is no doubt that using the explicit `int main(void)` form is better — but at the moment, the `int main()` form is also standard-compliant, even if not the preferred notation. Similar comments apply to the non-prototype style of function definition. The old style is still standard-compliant; it simply shouldn't be used. As you reworded the answer (with 'is obsolete'), that deals with my quibbling (which was meant to be small-scale quibbling, not a major exercise in the philosophy of how to write good C code), so all is well, though I would have used 'obsolescent' rather than 'obsolete'. – Jonathan Leffler Aug 26 '20 at 16:53
0

Static variables can also be declared at local scope. static duration means that the object or variable is allocated when the program starts and is deallocated when the program ends. ( from here )

So what this means for your example program is that 2 is correct:

The following example code, coupled with the statement at top illustrates why:

Initial call:

static int x = 0;  // unlike non-static variables, initialization is executed 
                   // only once on 1st call to function.
                   // Also unlike non-static, local variables, locally created static 
                   // variables are initialized to 0 automatically  
                   // making the explicit assignment to 0 unnecessary. 
                   // (although still a good habit. :)) 
...
x++; //x==1

2nd call:

static x = 0 //skipped 
...
x++; //x==2

3rd call:

static x = 0 //skipped 
...
x++; //x==3

And so on, until end of program...

(Having replaced x += 1; with its idiomatic shortcut syntax: x++;)

ryyker
  • 22,849
  • 3
  • 43
  • 87