Home > OS >  Is it possible to access static local variable outside the function where it is declared?
Is it possible to access static local variable outside the function where it is declared?

Time:08-29

For a static variable defined within a C function, like below:

int f1()
{
   static int var2 = 42;
   var2  ;
   printf("var2=%d\n", var2);
}

The var2 will be stored in the bss segment:

0000000000004014 l     O .data  0000000000000004              var2.2316

There are 2 aspects about the var2:

  • Its lifetime is the same as the whole program.
  • But its scope is limited to within f1().

The bss section is meant for uninitialized global data. While the data section is meant for initialized global data. The var2 lives in bss so it must be global in a sense.

I think the reason that var2 can only be accessed within f1() is just some syntactical rule placed by the compiler. If we iterate through the bss section, the var2 must be accessible from outside the f1(). Am I right on this? Thanks.

CodePudding user response:

Well you have raw access to memory, so the world's your oyster, but their limited access scope is exactly the whole point of using static local variables.

They're global state with controlled access, so you can apply local reasoning.

If you can access them externally, then local reasoning goes out the door. At that point, one should think: why not just use a regular global?

CodePudding user response:

Two execution environments are defined: freestanding and hosted. In both cases, program startup occurs when a designated C function is called by the execution environment. All objects with static storage duration shall be initialized (set to their initial values) before program startup. The manner and timing of such initialization are otherwise unspecified. Program termination returns control to the execution environment.

An object whose identifier is declared without the storage-class specifier _Thread_local, and either with external or internal linkage or with the storage-class specifier static, has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.

Your static local variable has static storage duration and will be initialized before program execution starts (ie before main is called). You can access it via a pointer to it. The pointer can be only obtained by calling the function.

int *func()
{
     static int x;
     return &x
}

CodePudding user response:

The following is more or less hacker stuff, in addition to other answers, not from the viewpoint of a language lawyer.

I think the reason that var2 can only be accessed within f1() is just some syntactical rule placed by the compiler.

To be picky, this is true only if the compiler is compliant to the standard. ;-) It is the standard that defines the rule. The technical term is "scope".

If we iterate through the bss section, the var2 must be accessible from outside the f1(). Am I right on this?

Yes. The section exists as long as the program runs. You can use a pointer into this section and access any variable living there. This holds true for the data section, too, of course.

You can also use a pointer to access any dynamic variable. Commonly these are allocated on the stack. To get a grip on a specific value can be quite tricky, though.

But all these accesses are application specific, compiler dependent, and system dependent, at least. You will probably break some rules. But in principle, nothing can stop you.


The bss section is meant for uninitialized global data. While the data section is meant for initialized global data.

This is only true if you mean "explicitly initialized to non-zero values".

Both sections are initialized before main() starts. All values in bss are zeroed, and all values in data are set to their non-zero values. A variable explicitly initialized to a zero value will commonly be allocated in bss.

The reason for the existence of separate sections is to save space in the executable. The bss section is commonly not stored, it is only defined. It does not makes sense to store a whole bunch of zeroes, the startup code will zero the complete section.

The var2 lives in bss

var2 does not live in the bss segment, but in the data segment, as the cutout clearly shows. Your var is initialized with 42, which is apparently non-zero.

CodePudding user response:

There are 2 aspects about the var2:

  • Its lifetime is the same as the whole program.
  • But its scope is limited to within f1().

Yes and no. Lifetime is a property of objects. Scope is a property of identifiers (names). That the scope of var2 is from its declaration in f1() to the end of the function is about the region of the source wherein that name identifies the object in question. On the other hand, that the lifetime of the object identified by var2 inside that scope is the same as the whole program's is about the object itself.

The bss section is meant for uninitialized global data. While the data section is meant for initialized global data. The var2 lives in bss so it must be global in a sense.

Be very careful about trying to infer language semantics from implementation details. It is very easy to get that wrong, and very hard to get it right in all details. In this particular case, the object in question is global in exactly the sense that its lifetime is the same as the whole program's, which you already knew.

For the record, "global" is not a C-language term. When people say "global variable" in C context, they usually mean a variable more properly described as having external linkage, which necessarily identifies an object having static storage duration (i.e. the whole execution of the program). That's not what you're looking at in the case of var2.

I think the reason that var2 can only be accessed within f1() is just some syntactical rule placed by the compiler.

More or less yes. The object can be accessed by name only within the scope of that name. This is among the semantic rules of the C language. It is essentially the definition of "scope".

If we iterate through the bss section, the var2 must be accessible from outside the f1(). Am I right on this?

How do you propose to "iterate through the bss section"? In the first place, that's a characteristic of some executable file formats, not a runtime characteristic of the program. But perhaps you mean "iterate through memory", but even then, C does not define a way to do that.

With that said, if f1() published a pointer to its var2 variable, via an out variable, for example, that pointer could indeed be used outside the function to access that object. Like this, for example:

int f1(int **pptr) {
   static int var2 = 42;
   *pptr = &var2;
   var2  ;
   return printf("var2=%d\n", var2);
}

// ...

void other_function() {
    int *ptr;
    int res = f1(&ptr);
    printf("%d\n", *ptr);
}
  •  Tags:  
  • c
  • Related