Difference between C global and local _static_ variables? - c

My C is quite rusty, please help me out.
static int i = 42;
int main()
{
}
creates a variable i with global scope and internal linkage. Meaning anyone can refer to it but only entries within the translation unit(.c file) will not break the linker. It is allocated during program linking and is initialized before main() is entered.
void foo()
{
static int i = 69;
}
creates a variable with function scope and no linkage. Meaning nothing outside of foo() can refer to it and even if the compiler didn't cry out, taking the address of this (essentially protected global) variable is UB. It is allocated during program linking and is initialized when foo() is first called.
Please correct me!

creates a variable i with global scope and internal linkage. Meaning anyone can refer to it but only entries within the translation unit(.c file) will not break the linker. It is allocated during program linking and is initialized before main() is entered.
Correct, except the formal term is file scope (outside any function), not to mixed up with "global" which can often mean accessible everywhere. In this case the variable is declared at file scope but it is not "globally" accessible. Generally, the informal term "global" is used together with the formal term external linkage and usage of the extern keyword.
creates a variable with function scope and no linkage.
No, it creates a variable with block scope. There exists a formal term function scope but it refers to the scope of goto labels. C has four scopes: file scope, function scope, block scope and function prototype scope. Those who aren't language lawyers or spaghetti programmers only need to know about file scope and block scope.
Meaning nothing outside of foo() can refer to it
Correct.
even if the compiler didn't cry out, taking the address of this (essentially protected global) variable is UB
No, this is wrong. Scope doesn't determine if a variable can be accessed or not, storage duration does. Both your examples declare variables with the same static storage duration but with different scopes. A variable with static storage duration persists and remains valid throughout the execution of the program.
Therefore it is fine and well-defined to return a pointer to a block scope variable with static storage duration. (It may not be thread-safe however, but that's another story.)
It is allocated during program linking
Correct.
and is initialized when foo() is first called.
No, this is wrong. All variables with static storage duration, regardless of their scope, are initialized before main() is called. Either to an explicit initializer as in your examples (typically meaning it gets allocated in a segment named .data) or to zero in case it wasn't explicitly initialized (all static storage variables set to zero typically gets allocated in a segment named .bss).

Related

Why and where to use a global variable and a static global variable in C?

I have read about global and local variables and static keyword, but i dont know which is the difference between something like this:
int x; //Global variable
int main(){
//Code...
}
And this:
static int x; //Static Global variable
int main(){
//Code...
}
I know some properties of the static keyword, and i know why is useful for local variables, but i dont know which is the use for global variables
I have read that using static for global variables is used for accesing the variable only in the C file it is declared/defined, but, i mean, if we dont use extern we just cant access that global variable in other c files anyway
I think that a "static global" variable is used to prevent the use of the extern keyword in order to prevent the use of that variable in multiple C files, is that correct?
Thanks in advance!
"Global" is not a formal term, but it generally means "variable that can be accessed anywhere". Therefore global.
To dive into some formal terms:
The formal and correct term for a variable declared outside a function is declared at file scope.
What formally defines how a variable may be accessed in C is referred to as linkage.
A variable declared at file scope generally has external linkage and can be referred to from elsewhere with extern.
So the correct term to use for your first example is "file scope variable with external linkage".
Whenever we add the storage class specifier static to a declaration, we force the variable or function to instead get internal linkage. This means that it is only accessible from within the translation unit (the .c file and all .h files it includes) where it was declared.
It is the opposite of global, so saying "static global" doesn't make any sense. You cannot refer to such a variable with extern. Instead the correct term is "file scope variable with internal linkage".
The main purpose of static is indeed private encapsulation, since the internal linkage guarantees that the variable or function cannot be accessed by other .c files.
But static also at the same time gives static storage duration to a variable, meaning it is guaranteed to persist throughout the execution of the program and that it has some initialization rules guaranteed. Now as it happens, variables at file scope always gets static storage duration, static or not, so it isn't very relevant to your example. But as you earlier discovered, static storage duration does make a big difference for local variables, since their value will then be preserved throughout multiple function calls.
More details here: What does the static keyword do in C?
Yes, it is correct.
A global static variable can only be accessed in the file where it is created (file scope).

Where is the local static variable stored? If it is data segment, why its scope is not whole program?

If static local variable also stored in the data segment, why can't values are not persist for variable which is used in two different functions. example like this.
void func()
{
static int i=0;
i++;
}
void func1()
{
i++; // here i is stored in the data segment,
// then the scope should be available for entire program
}
Why the value 'i' is only accessible to block scope if is stored in data segment? it might be a silly question but I am trying to understand to concept. Please help me to understand concept. Thanks in advance.
You need to differentiate between the scope and the lifetime of a variable.
In simple words:
"scope" means the region of your source code where the variable is known to the compiler. If a variable is (by the rules) not visible to the compiler, it will refuse to compile accesses to it.
"lifetime" means the time beginning with the allocation of memory for the variable until the moment the memory is assigned to another variable or released. A static variable lives as long as the program runs. A non-static variable lives just as long as its scope is in control.
However, just because both scope and lifetime of a variable are "finished", that does not mean that the memory disappears. The physical cells are still there, and they keep their last contents. That's why you can program functions that return a pointer to some local variable, and retrieve that variables contents after both the scope and the lifetime of the variable are gone. This is a fine example of a beginner's confusing issue.
Consider a compiler for an embedded processor like the 8051. Granted, a quite old and simple machine, but a good example. This compiler will commonly put local variables in its data segment. But to use the limited memory space (128 bytes in total, including working registers and stack) the same memory locations are re-used for variables with non-overlapping lifetimes. Eventhough, you could access any memory from all of the program.
Now, language lawyers, start picking on me. ;-)
A variable in C consists of two things:
A name, called an identifier. An identifier has a scope, which is a region of the program source code in which it is visible (may be used).
A region of storage (memory), called an object. An object has a lifetime, which is a portion of program execution during which memory is reserved for it. This is also called storage duration.
For a variable declared inside a function, its identifier has block scope, and the identifier is visible only from its declaration to the } that closes the innermost block it is in. (A block is a list of statements and declarations inside { and }.)
Inside a function, declaring a variable with static makes its object have static storage duration, causing it to exist for all of program execution, but it does not change the scope of its identifier. The object exists throughout program execution, but the identifier is visible only inside the function.
When another function is called, the object still exists (and it can be used if the function has its address, perhaps because it has been passed as a parameter). However, the identifier for the variable is not known inside the source code of other functions, so they cannot use the identifier.

Assignment to static variable is ignored

I have following piece of code:
#include <stdio.h>
int f1()
{
static int s=10;
printf("s=%d\n",s++);
}
int main()
{
f1();
f1();
return 0;
}
The output is:
s=10
s=11
Why is the line static int s=10 ignored at the second time, when f1 is called?
That is no assignment, but an initializer. Local static variables are only initialized once at program startup like global variables. They keep their last assigned value even between invocations of the function. Thus after your first call, it retains the value 11. In fact, they are like file-scope static variables, with their name only known in the scope of the block they are declared (but you can pass them by pointer).
Drawback is they only exist once. If you invoke the same function from multiple threads, they all share the same variable.
Try a third call: you will get 12.
Note: the initializer must be a constant expression. Try static int s = 10, t = s + 5; and read the compiler error message.
Initialization of a static variable is one-time (with the time of initialization guaranteed to occur before the first call, which could occur at compile time or at run time; compiler dependent). That's the main reason to use them.
The static variables are initialized only once, conceptually even before application has started.
From C11 (N1570) §5.1.2/p1 Execution environments:
All objects with static storage duration shall be initialized (set to
their initial values) before program startup.
along with §6.2.4/p3 Storage durations of objects:
Its lifetime is the entire execution of the program and its stored
value is initialized only once, prior to program startup.
As others have said, a static variable at function scope is initialized only once. So the assignment doesn't happen on subsequent calls to the function.
Unlike other local variables, a static local is not defined on the stack but in the data segment, probably in the same location as global variables. Globals are also initialized at application startup (they have to, since they don't live inside of a function and therefore can't be executable code), so conceptually you can think of a static variable as a global variable with limited visibility.
From the C89 Standard HTML version at 3.1.2.4 Storage durations of objects it specifies:
An object declared with external or internal linkage, or with the storage-class specifier static has static storage duration. For such an object, storage is reserved and its stored value is initialized only once, prior to program startup. The object exists and retains its last-stored value throughout the execution of the entire program
(The emphasis is mine)
So it says that everytime you use the static qualifier, that variable preserves its value across multiple function calls.
Local variables that are not static are initialized everytime you call the function that delcares them, so they do not preserve their value across function calls.
Hope this helped!

A static variable and a global variable both reside in data segment. Still, static variable has scope limited. Why?

In a typical C program, both static variable and global variable reside on the data segment. Still the scope of static variable is limited to file. On the contrary, the global variable can be accessed from anywhere. Why does it happen, although both reside in the same memory?
By design.
static at global scope is the keyword you use to mean "I want these variables limited in scope; I do not want to have to care what other modules have declared variables of the same name." The reason using this keyword does a different thing to not using it is in fact exactly the reason for its existence.
Note the keyword means different things in different contexts; at function scope static means "the contents of this variable should persist between function calls".
The actual arrangement of data in memory that results is an implementation detail, and will vary between compilers and platforms.
Why does it happen, although both resides in the same memory?
Short answer:-
From the C11 standard ( 6.2.2 Linkages of identifiers) para 4 :
If the declaration of a file scope identifier for an object or a
function contains the storageclass specifier static, the identifier
has internal linkage.
Internal linkage means that its visible only inside its translational unit.
Detailed answer:
A global variable(without static) has external linkage which means it is visible to other translational units.
When you declare static variables with file scope it has internal linkage but when you declare it with block scope it has no linkage.
Lets understand few terms specifically .( inspired from C keywords (static))
A C variable has one of the following linkages:
no linkage :- Variables with block scope have no linkage.It means they are private to the block in which they are defined . All variables with automatic, thread and dynamic storage durations have this linkage, as well as variables declared static at block scope.
A variable with file scope can have either internal or external linkage.
internal linkage :- The variable can be referred to from all scopes in the current translation unit. All variables which are declared at file scope have this linkage, including variables declared static at file scope.
external linkage :- The variable can be referred to from any other translation units in the entire program. All variables which are declared either extern or const with no explicit storage-class specifier, but not static, have this linkage.
e.g-
int i = 5; // file scope, external linkage
static int j = 3; // file scope, internal linkage
...
...
int main()
{
...
...
}
int func ()
{
static int num;// block scope – no linkage
. . .
}
By declaring a variable static on file level (static within function has a different meaning) you forbid other units to access it, e.g. if you try to use the variable inside another unit (declared with extern), linker won't find this symbol.
Emphasis mine :)
The idea of static variables is that they're not global and don't 'pollute' the global namespace. It means I can use the variable 'count' in 5 different functions and they won't clash. Scope confines variables to their context.
Technically you can access anything. The compiler just wouldn't give you a memory address - you would have to get it yourself. Somehow.

Is it correct to call a static variable local?

It is known that the C language supports two kinds of memory allocation through the variables in C programs:
1) Static allocation is what happens when you declare a static
variable. Each static variable defines one block of space, of a fixed
size. The space is allocated once, when your program is started, and
is never freed.
2) Automatic allocation happens when you declare an automatic
variable, such as a function argument or a local variable. The space
for an automatic variable is allocated when the compound statement
containing the declaration is entered, and is freed when that compound
statement is exited.
(this is a full quote from http://www.cs.utah.edu/dept/old/texinfo/glibc-manual-0.02/library_3.html)
The question is: is it correct to call a static variable in a function "local" in terms of memory allocation and why?
Thanks to everyone in advance.
P.S. any quotes from the C standard are welcome.
C standard doesn't define the term of local variable. Automatic and static refer to storage duration.
C11 (n1570), § 6.2.4 Storage durations of objects
An object has a storage duration that determines its lifetime.
You could call it a "function-local static variable" or something like that, but if you simply call it a "local variable" you may find that people are surprised when they find out it's actually static, and therefore has some of the properties of a global variable.
There are two types of static variables in C.
The global static variables, where the static states that these variables can only be seen in this translation-unit.
Static variables with a local scop (i.e. in function). These are initialized once and keep their value event after going out of scope.
And to you question: no, a variable can't be static and automatic at the same time.
If you check their addresses, you will se that the static variable does not live on the current stack frame.
In the context of variables, the term local most often denotes visibility and scope rather than the storage mechanism and lifetime.
Using the term local variables in C is in fact inaccurate as the standard never talks about that.
Informally, a static variable inside a function could be said to be local within the visible scope of the function, but not much more than that.
I would suggest against using the term local variables at all. Instead, one should talk about static variables within a function, automatic variables, static variables in the file scope and globals.
The question is: is it correct to call a static variable in a function "local" in terms of memory allocation and why?
Static variables are stored in the data section of the memory allocated to the program.
Even though if the scope of a static variable ends , it can still be accessed outside its
scope , this may indicate that , the contents of data segment , may be independent
of scope.
Example
#include <stdio.h>
int increment(void);
int main()
{
printf("\ni = %d",increment());
printf("\ni = %d",increment());
printf("\ni = %d",increment());
}
int increment(void)
{
static int i = 1;
return i++ ;
}
In the above example , after each function call to increment() , the static variable i inside the function goes out of scope every time the function returns but persistently
retains its value. This is only possible because the variable is not on the same same stack as the function , but it is present entirely in a different memory area , the data segment.

Resources