In what segment (.BSS, .DATA, other) of an executable file are static variables stored so that they don\'t have name collision? For example:
foo.c:
In fact, a variable is tuple (storage, scope, type, address, value):
storage : where is it stored, for example data, stack, heap...
scope : who can see us, for example global, local...
type : what is our type, for example int, int*...
address : where are we located
value : what is our value
Local scope could mean local to either the translational unit (source file), the function or the block depending on where its defined. To make variable visible to more than one function, it definitely has to be in either DATA or the BSS area (depending on whether its initialized explicitly or not, respectively). Its then scoped accordingly to either all function(s) or function(s) within source file.
static variable stored in data segment or code segment as mentioned before.
You can be sure that it will not be allocated on stack or heap.
There is no risk for collision since static
keyword define the scope of the variable to be a file or function, in case of collision there is a compiler/linker to warn you about.
A nice example
Well this question is bit too old, but since nobody points out any useful information: Check the post by 'mohit12379' explaining the store of static variables with same name in the symbol table: http://www.geekinterview.com/question_details/24745
How to find it yourself with objdump -Sr
To actually understand what is going on, you must understand linker relocation. If you've never touched that, consider reading this post first.
Let's analyze a Linux x86-64 ELF example to see it ourselves:
#include <stdio.h>
int f() {
static int i = 1;
i++;
return i;
}
int main() {
printf("%d\n", f());
printf("%d\n", f());
return 0;
}
Compile with:
gcc -ggdb -c main.c
Decompile the code with:
objdump -Sr main.o
-S
decompiles the code with the original source intermingled-r
shows relocation informationInside the decompilation of f
we see:
static int i = 1;
i++;
4: 8b 05 00 00 00 00 mov 0x0(%rip),%eax # a <f+0xa>
6: R_X86_64_PC32 .data-0x4
and the .data-0x4
says that it will go to the first byte of the .data
segment.
The -0x4
is there because we are using RIP relative addressing, thus the %rip
in the instruction and R_X86_64_PC32
.
It is required because RIP points to the following instruction, which starts 4 bytes after 00 00 00 00
which is what will get relocated. I have explained this in more detail at: https://stackoverflow.com/a/30515926/895245
Then, if we modify the source to i = 1
and do the same analysis, we conclude that:
static int i = 0
goes on .bss
static int i = 1
goes on .data
The answer might very well depend on the compiler, so you probably want to edit your question (I mean, even the notion of segments is not mandated by ISO C nor ISO C++). For instance, on Windows an executable doesn't carry symbol names. One 'foo' would be offset 0x100, the other perhaps 0x2B0, and code from both translation units is compiled knowing the offsets for "their" foo.
The storage location of the data will be implementation dependent.
However, the meaning of static is "internal linkage". Thus, the symbol is internal to the compilation unit (foo.c, bar.c) and cannot be referenced outside that compilation unit. So, there can be no name collisions.