I want to know what actually going under the hood,how compiler treats static variables. Unlike auto variable, static variable's value persist even after the end of block but how compilers actually handle this?
When you declare a variable or a method as static, it belongs to the class, rather than a specific instance. This means that only one instance of a static member exists, even if you create multiple objects of the class, or if you don't create any. It will be shared by all objects.
A variable is declared as static to get the latest and single copy of its value; it means the value is going to be changed somewhere.
Static initialization happens first and usually at compile time. If possible, initial values for static variables are evaluated during compilation and burned into the data section of the executable.
When a member is declared static, it can be accessed before any objects of its class are created, and without reference to any object.
Unlike local variables which go on stack, static variables are kept in special data segments. Which segment your static variable goes to depends on if they are 0 initialized or not. 0 initialized static data goes in .BSS (Block Started by Symbol), non 0 initialized data goes in .DATA.
If you want to learn more what about different segments within executable files, this Wikipedia entry is a good starting point. I also highly recommend Chapter 7 in Computer Systems: A Programmer's Perspective by Randal E. Bryant and David R. O'Hallaron.
I'm describing here one particular scenario. You need to take into account that details will vary from one architecture to another, from one OS to another, so on and so forth. However, the general layout of executable files remains as described. Exciting stuff indeed!
EDIT:
The author kindly asked me to clarify:
what is the point of dividing the 0 initialized variable to .bss and non 0 initialized to .data?
From Section 7.4 in Computer Systems: A Programmer's Perspective on the .BSS section:
This section occupies no actual space in the object file; it is merely a place holder. Object file formats distinguish between initialized and uninitialized variables for space efficiency: uninitialized variables do not have to occupy any actual disk space in the object file.
And, from Wikipedia:
Typically only the length of the .BSS section, but no data, is stored in the object file. The program loader allocates and initializes memory for the bss section when it loads the program.
To summarize: it's a mechanism for saving memory.
Typical C compilers produce assembly output that creates four "sections" of memory. The linker/loader generally combines various items labelled with the same section together as it loads the program into memory. The most common sections are:
"text": This is actual program code. It is considered read-only (linker/loader on some machines might place it in ROM, for example).
"data": This is simply an allocated area of RAM, with initial values copied from the executable file. The loader will allocate the memory, then copy in its initial contents.
"bss": Same as data, but initialized to zeros.
"stack": Simply allocated by the loader for its program stack.
Global and static variables are placed in "data" and "bss", and therefore have a lifetime of the life of the program. Static variables do not, however, place their names in the symbol table, so they can't be linked externally like globals. Visibility and lifetime of variables are totally separate concepts: C's syntax confuses the two.
"Auto" variables are typically allocated on the stack during program execution (though if they are very large, they may be allocated on the heap instead). They only exist within their stack frame.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With