c

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


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 .data segment (because it is explicitly initialized to 42, thanks to @busybee pointing this out):

0000000000004014 l     O .data  0000000000000004              var2.2316

The var2 will be stored in the .bss segment if I don't explicitly initialize it or initialize it to 0):

000000000000401c l     O .bss   0000000000000004              var2.2316

There are 2 aspects about the var2:

The bss section is meant for uninitialized global data. While the data section is meant for initialized yet still 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.


Solution

  • 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);
    }