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?
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.
static
variables are global variables with limited scope. @user3386109
static
/global variables exist for the lifetime of the program.static
/global are initialized at program start-up to either:A. If not explicitly initialize: to the bit pattern
0
.
B. Otherwise to to an explicit value likedouble x = 1.23;
static
variables scope is either limited toA. If defined outside a function: file scope, only code within the file can "see" the variable.
B. If defined inside a function: block scope: only code within the block may "see" the variable.There is only one instance of the
static
variable within its scope unless a lower scope defines another with the same name. The compiler "knows" which same named variable to access by using the closest scope first. It is not re-created or re-initialized, even if inside a function.
Note: With 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
This code:
void function()
{
static int var = 6;
// Make something with this variable
var++;
}
is 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's a kind of "global" variable whose name, however, doesn't conflict with any other global variable.
来源:https://stackoverflow.com/questions/30581675/what-actually-compiler-does-when-we-declare-static-variables