Where are static local variables stored in memory? Local variables can be accessed only inside the function in which they are declared.
Global static variables go into the .data segment.
If both the name of the static global and static local variable are same, how does the compiler distinguish them?
As mentioned by dasblinken, GCC 4.8 puts local statics on the same place as globals.
More precisely:
static int i = 0
goes on.bss
static int i = 1
goes on.data
Let's analyze one Linux x86-64 ELF example to see it ourselves:
To reach conclusions, we need to understand the relocation information. If you've never touched that, consider reading this post first.
Compile it:
Decompile the code with:
f
contains:Which does 3 accesses to
i
:4
moves to theeax
to prepare for the incrementd
moves the incremented value back to memory13
movesi
to theeax
for the return value. It is obviously unnecessary sinceeax
already contains it, and-O3
is able to remove that.So let's focus just on
4
:Let's look at the relocation data:
which says how the text section addresses will be modified by the linker when it is making the executable.
It contains:
We look at
.rela.text
and not the others because we are interested in relocations of.text
.Offset 6
falls right into the instruction that starts at byte 4:From our knowledge of x86-64 instruction encoding:
8b 05
is themov
part00 00 00 00
is the address part, which starts at byte6
AMD64 System V ABI Update tells us that
R_X86_64_PC32
acts on 4 bytes (00 00 00 00
) and calculates the address as:which means:
S
: the segment pointed to:.data
A
: theAdded
:-4
P
: the address of byte 6 when loaded-P
is needed because GCC usedRIP
relative addressing, so we must discount the position in.text
-4
is needed becauseRIP
points to the following instruction at byte0xA
butP
is byte0x6
, so we need to discount 4.Conclusion: after linking it will point to the first byte of the
.data
segment.Static variables go into the same segment as global variables. The only thing that's different between the two is that the compiler "hides" all static variables from the linker: only the names of extern (global) variables get exposed. That is how compilers allow static variables with the same name to exist in different translation units. Names of static variables remain known during the compilation phase, but then their data is placed into the
.data
segment anonymously.Static variable is almost similar to global variable and hence the uninitialized static variable is in BSS and the initialized static variable is in data segment.