2

We all know the common example to how static variable work - a static variable is declared inside a function with some value (let's say 5), the function adds 1 to it, and in the next call to that function the variable will have the modified value (6 in my example).

How does that happen behind the scene? What makes the function ignore the variable declaration after the first call? How does the value persist in memory, given the stack frame of the function is "destroyed" after its call has finished?

localhost
  • 461
  • 4
  • 19
  • If you really want to know what happens behind the scenes, you need to study the assembly output generated by the compiler. – Jabberwocky Oct 27 '20 at 07:29

3 Answers3

6

The variable isn't stored in the stack frame, it's stored in the same memory used for global variables. The only difference is that the scope of the variable name is the function where the variable is declared.

Barmar
  • 741,623
  • 53
  • 500
  • 612
6

static variables and other variables with static storage duration are stored in special segments outside the stack. Generally, the C standard doesn't mention how this is done other than that static storage duration variables are initialized before main() is called. However, the vast majority of real-world computers work as described below:

If you initialize a static storage duration variable with a value, then most systems store it in a segment called .data. If you don't initialize it, or explicitly initialize it to zero, it gets stored in another segment called .bss where everything is zero-initialized.

The tricky part to understand is that when we write code such as this:

void func (void)
{
  static int foo = 5;   // will get stored in .data
  ...

Then the line containing the initialization is not executed the first time the function is entered (as often taught in beginner classes) - it is not executed inside the function at all and it is always ignored during function execution.

Before main() is even called, the "C run-time libraries" (often called CRT) run various start-up code. This includes copying down values into .data and .bss. So the above line is actually executed before your program even starts.

So by the time func() is called for the first time, foo is already initialized. Any other changes to foo inside the function will happen in run-time, as with any other variable.

This example illustrates the various memory regions of a program. What gets allocated on the stack and the heap? gives a more generic explanation.

Lundin
  • 195,001
  • 40
  • 254
  • 396
3

Quoting C11, chapter 6.2.4

An object whose identifier is declared [...] with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

In a typical implementation, the objects with static storage duration are stored either in the data segment or the BSS (based on whether initialized or not). So every function call does not create a new variable in the stack of the called function, as you might have expected. There's a single instance of the variable in memory which is accessed for each iteration.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261