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
:
f1()
.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.
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 withinf1()
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, thevar2
must be accessible from outside thef1()
. 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);
}