Where are static variables stored in C and C++?

2018-12-31 05:02发布

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:                         bar.c:
static int foo = 1;            static int foo = 10;
void fooTest() {               void barTest() {
  static int bar = 2;            static int bar = 20;
  foo++;                         foo++;
  bar++;                         bar++;
  printf("%d,%d", foo, bar);     printf("%d, %d", foo, bar);
}                              }

If I compile both files and link it to a main that calls fooTest() and barTest repeatedly, the printf statements increment independently. Makes sense since the foo and bar variables are local to the translation unit.

But where is the storage allocated?

To be clear, the assumption is that you have a toolchain that would output a file in ELF format. Thus, I believe that there has to be some space reserved in the executable file for those static variables.
For discussion purposes, lets assume we use the GCC toolchain.

16条回答
残风、尘缘若梦
2楼-- · 2018-12-31 05:44

you already know either it store in bss(block start by symbol) also referred as uninitialized data segment or in initialized data segment.

lets take an simple example

void main(void)
{
static int i;
}

the above static variable is not initialized , so it goes to uninitialized data segment(bss).

void main(void)
{
static int i=10;
}

and of course it initialized by 10 so it goes to initialized data segment.

查看更多
有味是清欢
3楼-- · 2018-12-31 05:46

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.

查看更多
裙下三千臣
4楼-- · 2018-12-31 05:48

It depends on the platform and compiler that you're using. Some compilers store directly in the code segment. Static variables are always only accessible to the current translation unit and the names are not exported thus the reason name collisions never occur.

查看更多
墨雨无痕
5楼-- · 2018-12-31 05:55

When a program is loaded into memory, it’s organized into different segments. One of the segment is DATA segment. The Data segment is further sub-divided into two parts:

Initialized data segment: All the global, static and constant data are stored here.
Uninitialized data segment(BSS): All the uninitialized data are stored in this segment.

Here is a diagram to explain this concept:

enter image description here


here is very good link explaining these concepts:

http://www.inf.udec.cl/~leo/teoX.pdf

查看更多
其实,你不懂
6楼-- · 2018-12-31 05:55

I don't believe there will be a collision. Using static at the file level (outside functions) marks the variable as local to the current compilation unit (file). It's never visible outside the current file so never has to have a name.

Using static inside a function is different - the variable is only visible to the function, it's just its value is preserved across calls to that function.

In effect, static does two different things depending on where it is. In oth cases however, it limits the visibility of the variable to prevent namespace clashes,

Having said that, I believe it would be stored in DATA which tends to have initialized variable. The BSS originally stood for byte-set-<something> which held variables which weren't initialized.

查看更多
萌妹纸的霸气范
7楼-- · 2018-12-31 05:55

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.

查看更多
登录 后发表回答