What does the compiler really do when we declare static variables?

I want to know what is really happening under the hood, how the compiler treats static variables. Unlike an automatic variable, the static value of the variable is preserved even after the end of the block, but how do compilers really handle this?

+6
source share
4 answers

Unlike local variables that go onto the stack, static variables are stored in special data segments. Which segment your static variable occupies depends on whether they were initialized or not. 0 initialized static data goes to .BSS (Block Started by Symbol), but not initialized data goes to .DATA .

If you want to know more about the different segments in executables, this Wikipedia is a good starting point. I also highly recommend Chapter 7 in computer systems: the perspective of programmer Randall E. Bryant and David R. O'Hallaron.

I am describing one specific scenario here. You must bear in mind that details will vary from one architecture to another, from one OS to another, etc. Etc. However, the general layout of the executable files remains as described. Really exciting stuff!

EDIT:

The author kindly asked me to clarify:

what is the point of dividing the null variable 0 by .bss and non 0 initialized in .data?

From Section 7.4 on Computer Systems: A Programmer's Perspective in .BSS Section:

This section does not take up actual space in the object file; it's just a place holder. Object file formats distinguish between initialized and uninitialized variables for space efficiency: uninitialized variables should not occupy any actual disk space in the file object.

And, from Wikipedia :

Usually only .BSS section length is used , but no data. in the object file. The program loader allocates and initializes memory for the bss section when loading the program.

To summarize: this is a memory saving mechanism.

+7
source

Typical C compilers produce an assembly that creates four "sections" of memory. The compiler / loader usually combines the various elements marked with the same section, together with loading the program into memory. The most common sections are:

"text": This is the actual program code. This is considered read-only (for example, the linker / loader on some machines may put it in ROM).

"data": This is just the allocated RAM area, with the original values โ€‹โ€‹copied from the executable. The bootloader will allocate memory, then copy it to the original contents.

"bss": Same as data, but initialized with zeros.

"stack": just assigned by the loader for its program stack.

Global and static variables are placed in "data" and "bss" and, therefore, have a program life. However, static variables do not put their names in the symbol table, so they cannot be connected externally as global ones. The visibility and lifetime of variables are completely different concepts: the C syntax mixes the two.

"Automatic" variables are usually allocated on the stack during program execution (although if they are very large, they can be allocated instead of the heap). They exist only in the frame of the stack.

+3
source

This code:

void function() { static int var = 6; // Make something with this variable var++; } 

internally similar to this:

 int only_the_compiler_knows_this_actual_name = 6; void function() { // Make something with the variable only_the_compiler_knows_this_actual_name++; } 

In other words, it is a kind of global variable whose name, however, does not conflict with any other global variable.

+1
source

static variables are global variables with a limited scope. @ user3386109

  • static / there are global variables for the program lifetime.
  • static / global are initialized when the program starts:

    a. If not explicitly initialized: to bit scheme 0 .
    B. Otherwise, to an explicit value, for example double x = 1.23;

  • static scope of variables is limited

    a. If defined outside the function: area of โ€‹โ€‹the file, only the code inside the file can โ€œseeโ€ the variable.
    B. If defined inside a function: block area: only code inside a block can โ€œseeโ€ a variable.

  • Only one instance of the static variable exists within its scope, unless the bottom scope defines another with the same name. The compiler โ€œknowsโ€, with the same named variable for access, first using the nearest scope. It is not recreated or reinitialized, even if it is inside a function.

Note. When using multiple threads, other considerations apply - not shown.

 static int fred = 11; int sally = 21; void foo2(void) { static int fred = 31; int sally = 41; printf("static %d non-static %d\n", fred++, sally++); { printf("static %d non-static %d\n", fred++, sally++); { static int fred = 51; int sally = 61; printf("static %d non-static %d\n", fred++, sally++); } } } int main(void) { printf("static %d non-static %d\n", fred++, sally++); foo2(); printf("static %d non-static %d\n", fred++, sally++); foo2(); return 0; } 

Output

 static 11 non-static 21 static 31 non-static 41 static 32 non-static 42 static 51 non-static 61 static 12 non-static 22 static 33 non-static 41 static 34 non-static 42 static 52 non-static 61 
+1
source

Source: https://habr.com/ru/post/988339/


All Articles