CIsForCookies
CIsForCookies

Reputation: 12807

What happens to initialization of static variable inside a function

After stumbling onto this question and reading a little more here (c++ but this issue works the same in C/C++ AFAIN) I saw no mention to what is realy happening inside the function.

void f(){
  static int c = 0;
  printf("%d\n",c++);
}

int main(){
  int  i = 10;
  while(i--)
    f();
  return 0;
}

In this snippet, c lifetime is the entire execution of the program, so the line static int c = 0; has no meaning in the next calls to f() since c is already a defined (static) variable, and the assignment part is also obsolete (in the next calls to f()), since it only takes place at the first time.

So, what does the compiler do? does it split f into 2 functions - f_init, f_the_real_thing where f_init initializes and f_the_real_thing prints, and calls 1 time f_init and from that onward, only calls f_the_real_thing?

Upvotes: 5

Views: 5022

Answers (3)

Bathsheba
Bathsheba

Reputation: 234635

The C standard doesn't specify how the required behaviour for static storage duration must be implemented.

If you're curious about how your particular implementation handles this, then you can always check the generated assembly.

(Note that in your particular case, your code is vulnerable to concurrency issues centred around c++ not necessarily being atomic; also its vulnerability to int overflow, although i-- does act as an adequate termination condition.)

Upvotes: 4

Peter
Peter

Reputation: 36597

The first assignment is not "obsolete" - it ensures c is zero the first time f() is called. Admittedly that is the default for statics: if no initialiser is specified, it will be initialised to zero. But a static int c = 42 will ensure c has the value 42 the first time the function is called, and the sequence of values will continue from there.

The static keyword means that the variable has static storage duration. It is only initialised once (so will have that value the first time the function is called) but changes then persist - any time the value is retrieved, the value retrieved will be the last stored in the variable.

All the compiler does is place the variable c into an area of memory that will exist - and hold whatever value it was last set to - for as long as the program is running. The specifics of how that is achieved depends on the compiler.

However, I have never seen a compiler that splits the logic of the function into multiple parts to accommodate the static.

Upvotes: 8

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726479

Although the standard does not dictate how compilers must implement behavior, most compilers do a much less sophisticated thing: they place c into static memory segment, and tell the loader to place zero into c's address. This way f comes straight to pre-initialized c, and proceeds to printing and incrementing as if the declaration line where not there.

In C++ it optionally adds code to initialize c to static initialization function, which initializes all static variables. In this case, no call is required.

In essence, this amounts to c starting its lifetime before the first call to f. You can think of c's behavior as if it were a static variable outside f() with its visibility constrained to f()'s scope.

Upvotes: 6

Related Questions