Shadowing of static global and local identifiers - c

The following program was on a practice worksheet given out in class. We are asked to give its output, but from what I understand about linkage, file2.c should not have two instances of the static identifier b but the program compiles with a warning and runs just fine. My question is, why is this allowed? I thought the point of static linkage was to be able to access an identifier everywhere in that file?
CLARIFICATION: The question is about file2.c: there are two "static int b" declarations. Why is that allowed?
/* file1.c */
#include <stdio.h>
extern int a;
static int b;
void f(int);
void g(void);
int main() {
a = 10;
b = 20;
f(a);
f(b);
g();
printf("main: %d %d\n", a, b);
return 0;
}
/* file2.c */
include <stdio.h>
int a;
static int b;
void f(int c) {
static int b = 5;
a += b;
b += c;
printf("f: %d %d\n", a , b ) ;
}
void g(void) {
a += 5;
b = 10;
printf("g: %d %d\n", a , b);
}
Thank you in advance for any help (this is my first time posting so I apologize if there are formatting errors!).

The compiler creates a different instance for every global static variable, even when you have several such variables with identical names.
In fact, the compiler (or possibly, the preprocessor) implicitly changes the name of every such variable, according to the name of the source file which declares it.
You can prove this to yourself by declaring a global static variable in a header file, and then include this header file in several different source files. Try to set it to a different value in each source file, and you'll see that this variable retains its different value in each source file.
If you want to have the same instance of a global variable accessible in several source files, then you should refrain from declaring it static:
If you declare it in a header file, then use extern as prefix, and include the header file in every source file that makes use of this variable.
If you declare it in a source file, then you will have to declare it as extern in every other source file that makes use of this variable.
The address of an external global variable is determined only during linkage. This is in contrast with the following cases, in which the address of the variable is determined during compilation:
A local variable
A static local variable
A static global variable
A non-external global variable
I believe that the term static linkage refers to the linkage of compiled objects (or libraries) into the executable image during the build process, as opposed to dynamic linkage which refers to the linkage of compiled code (also known as DLL) into the executable image only during runtime.
UPDATE:
After reading your clarification, I understand that the only issue is with a local variable and a global variable of the same name (the static attribute makes no difference with regards to this issue).
Inside a function, a local variable is always "preferred by the compiler" over a global variable with the same name. In other words, in function f, all operations on variable b are applied on the local variable and not on the global variable.

Related

When using Static storage class, is stack used for Function implmentation? If yes, how does it work? If no, what is used? [duplicate]

I've seen the word static used in different places in C code; is this like a static function/class in C# (where the implementation is shared across objects)?
A static variable inside a function keeps its value between invocations.
A static global variable or a function is "seen" only in the file it's declared in
(1) is the more foreign topic if you're a newbie, so here's an example:
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
This prints:
a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60
This is useful for cases where a function needs to keep some state between invocations, and you don't want to use global variables. Beware, however, this feature should be used very sparingly - it makes your code not thread-safe and harder to understand.
(2) Is used widely as an "access control" feature. If you have a .c file implementing some functionality, it usually exposes only a few "public" functions to users. The rest of its functions should be made static, so that the user won't be able to access them. This is encapsulation, a good practice.
Quoting Wikipedia:
In the C programming language, static
is used with global variables and
functions to set their scope to the
containing file. In local variables,
static is used to store the variable
in the statically allocated memory
instead of the automatically allocated
memory. While the language does not
dictate the implementation of either
type of memory, statically allocated
memory is typically reserved in data
segment of the program at compile
time, while the automatically
allocated memory is normally
implemented as a transient call stack.
And to answer your second question, it's not like in C#.
In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.
There is one more use not covered here, and that is as part of an array type declaration as an argument to a function:
int someFunction(char arg[static 10])
{
...
}
In this context, this specifies that arguments passed to this function must be an array of type char with at least 10 elements in it. For more info see my question here.
Short answer ... it depends.
Static defined local variables do not lose their value between function calls. In other words they are global variables, but scoped to the local function they are defined in.
Static global variables are not visible outside of the C file they are defined in.
Static functions are not visible outside of the C file they are defined in.
Multi-file variable scope example
Here I illustrate how static affects the scope of function definitions across multiple files.
a.c
#include <stdio.h>
/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
https://stackoverflow.com/questions/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/
/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/
/* OK: extern. Will use the one in main. */
extern int i;
/* OK: only visible to this file. */
static int si = 0;
void a() {
i++;
si++;
puts("a()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
main.c
#include <stdio.h>
int i = 0;
static int si = 0;
void a();
void m() {
i++;
si++;
puts("m()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
int main() {
m();
m();
a();
a();
return 0;
}
GitHub upstream.
Compile and run:
gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o
Output:
m()
i = 1
si = 1
m()
i = 2
si = 2
a()
i = 3
si = 1
a()
i = 4
si = 2
Interpretation
there are two separate variables for si, one for each file
there is a single shared variable for i
As usual, the smaller the scope, the better, so always declare variables static if you can.
In C programming, files are often used to represent "classes", and static variables represent private static members of the class.
What standards say about it
C99 N1256 draft 6.7.1 "Storage-class specifiers" says that static is a "storage-class specifier".
6.2.2/3 "Linkages of identifiers" says static implies internal linkage:
If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.
and 6.2.2/2 says that internal linkage behaves like in our example:
In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function.
where "translation unit is a source file after preprocessing.
How GCC implements it for ELF (Linux)?
With the STB_LOCAL binding.
If we compile:
int i = 0;
static int si = 0;
and disassemble the symbol table with:
readelf -s main.o
the output contains:
Num: Value Size Type Bind Vis Ndx Name
5: 0000000000000004 4 OBJECT LOCAL DEFAULT 4 si
10: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 i
so the binding is the only significant difference between them. Value is just their offset into the .bss section, so we expect it to differ.
STB_LOCAL is documented on the ELF spec at http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html:
STB_LOCAL Local symbols are not visible outside the object file containing their definition. Local symbols of the same name may exist in multiple files without interfering with each other
which makes it a perfect choice to represent static.
Variables without static are STB_GLOBAL, and the spec says:
When the link editor combines several relocatable object files, it does not allow multiple definitions of STB_GLOBAL symbols with the same name.
which is coherent with the link errors on multiple non static definitions.
If we crank up the optimization with -O3, the si symbol is removed entirely from the symbol table: it cannot be used from outside anyways. TODO why keep static variables on the symbol table at all when there is no optimization? Can they be used for anything? Maybe for debugging.
See also
analogous for static functions: https://stackoverflow.com/a/30319812/895245
compare static with extern, which does "the opposite": How do I use extern to share variables between source files?
C++ anonymous namespaces
In C++, you might want to use anonymous namespaces instead of static, which achieves a similar effect, but further hides type definitions: Unnamed/anonymous namespaces vs. static functions
It depends:
int foo()
{
static int x;
return ++x;
}
The function would return 1, 2, 3, etc. --- the variable is not on the stack.
a.c:
static int foo()
{
}
It means that this function has scope only in this file. So a.c and b.c can have different foo()s, and foo is not exposed to shared objects. So if you defined foo in a.c you couldn't access it from b.c or from any other places.
In most C libraries all "private" functions are static and most "public" are not.
People keep saying that 'static' in C has two meanings. I offer an alternate way of viewing it that gives it a single meaning:
Applying 'static' to an item forces that item to have two properties: (a) It is not visible outside the current scope; (b) It is persistent.
The reason it seems to have two meanings is that, in C, every item to which 'static' may be applied already has one of these two properties, so it seems as if that particular usage only involves the other.
For example, consider variables. Variables declared outside of functions already have persistence (in the data segment), so applying 'static' can only make them not visible outside the current scope (compilation unit). Contrariwise, variables declared inside of functions already have non-visibility outside the current scope (function), so applying 'static' can only make them persistent.
Applying 'static' to functions is just like applying it to global variables - code is necessarily persistent (at least within the language), so only visibility can be altered.
NOTE: These comments only apply to C. In C++, applying 'static' to class methods is truly giving the keyword a different meaning. Similarly for the C99 array-argument extension.
static means different things in different contexts.
You can declare a static variable in a C function. This variable is only visible in the function however it behaves like a global in that it is only initialized once and it retains its value. In this example, everytime you call foo() it will print an increasing number. The static variable is initialized only once.
void foo ()
{
static int i = 0;
printf("%d", i); i++
}
Another use of static is when you implement a function or global variable in a .c file but don't want its symbol to be visible outside of the .obj generated by the file. e.g.
static void foo() { ... }
From Wikipedia:
In the C programming language, static is used with global variables and functions to set their scope to the containing file. In local variables, static is used to store the variable in the statically allocated memory instead of the automatically allocated memory. While the language does not dictate the implementation of either type of memory, statically allocated memory is typically reserved in data segment of the program at compile time, while the automatically allocated memory is normally implemented as a transient call stack.
I hate to answer an old question, but I don't think anybody has mentioned how K&R explain it in section A4.1 of "The C Programming Language".
In short, the word static is used with two meanings:
Static is one of the two storage classes (the other being
automatic). A static object keeps its value between invocations. The objects declared outside all blocks are always static and cannot be made automatic.
But, when the static keyword (big emphasis on it being used in
code as a keyword) is used with a declaration, it gives that object internal linkage so it can only be used within that translation unit. But if the keyword is used in a function, it changes the storage class of the object (the object would only be visible within that function anyway). The opposite of static is the extern keyword, which gives an object external linkage.
Peter Van Der Linden gives these two meanings in "Expert C Programming":
Inside a function, retains its value between calls.
At the function level, visible only in this file.
If you declare a variable in a function static, its value will not be stored on the function call stack and will still be available when you call the function again.
If you declare a global variable static, its scope will be restricted to within the file in which you declared it. This is slightly safer than a regular global which can be read and modified throughout your entire program.
A static variable is a special variable that you can use in a function, and it saves the data between calls, and it does not delete it between calls. For example:
void func(void) {
static int count; // If you don't declare its value, it is initialized with zero
printf("%d, ", count);
++count;
}
int main(void) {
while(true) {
func();
}
return 0;
}
The output:
0, 1, 2, 3, 4, 5, ...
In C, static has two meanings, depending on scope of its use. In the global scope, when an object is declared at the file level, it means that that object is only visible within that file.
At any other scope it declares an object that will retain its value between the different times that the particular scope is entered. For example, if an int is delcared within a procedure:
void procedure(void)
{
static int i = 0;
i++;
}
the value of 'i' is initialized to zero on the first call to the procedure, and the value is retained each subsequent time the procedure is called. if 'i' were printed it would output a sequence of 0, 1, 2, 3, ...
If you declare this in a mytest.c file:
static int my_variable;
Then this variable can only be seen from this file. The variable cannot be exported anywhere else.
If you declare inside a function the value of the variable will keep its value each time the function is called.
A static function cannot be exported from outside the file. So in a *.c file, you are hiding the functions and the variables if you declare them static.
Share what I learned about this point.
In C static is a declaration specifier, which falls into three categories:
storage classes: there are four classes: auto, static, extern and register.
type qualifiers: like keywords: const, volatile, etc.
type specifiers: like keywords: void, char, short, int, etc.
So static is a storage classes. It will determine the following three properties of each variable in a C program.
storage duration: means when memory is allocated for the variable and when the memory is released. A variable with static storage duration stays at the same memory location as long as the program is running.
scope: means the portion of the program text in which the variable can be accessed. A static variable has a file scope instead of a block scope.
linkage: means the extent to which the variable can be shared by different parts(or files) of a program. If a static variable is declared inside a block then it has no linkage. If a static variable is declared outside blocks, then it has internal linkage. Internal linkage makes it accessible in a single file.
The static storage class has a different effect on a variable depending on it is declared outside a block or inside a block. Need to consider case by case.
It is important to note that static variables in functions get initialized at the first entry into that function and persist even after their call has been finished; in case of recursive functions the static variable gets initialized only once and persists as well over all recursive calls and even after the call of the function has been finished.
If the variable has been created outside a function, it means that the programmer is only able to use the variable in the source-file the variable has been declared.
Static variables in C have the lifetime of the program.
If defined in a function, they have local scope, i.e. they can be accessed only inside those functions. The value of static variables is preserved between function calls.
For example:
void function()
{
static int var = 1;
var++;
printf("%d", var);
}
int main()
{
function(); // Call 1
function(); // Call 2
}
In the above program, var is stored in the data segment. Its lifetime is the whole C program.
After function call 1, var becomes 2. After function call 2, var becomes 3.
The value of var is not destroyed between functions calls.
If var had between non static and local variable, it would be stored in the stack segment in the C program. Since the stack frame of the function is destroyed after the function returns, the value of var is also destroyed.
Initialized static variables are stored in the data segment of the C program whereas uninitialized ones are stored in the BSS segment.
Another information about static: If a variable is global and static, it has the life time of the C program, but it has file scope. It is visible only in that file.
To try this:
file1.c
static int x;
int main()
{
printf("Accessing in same file%d", x):
}
file2.c
extern int x;
func()
{
printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
}
run gcc -c file1.c
gcc -c file2.c
Now try to link them using:
gcc -o output file1.o file2.o
It would give a linker error as x has the file scope of file1.c and the linker would not be able to resolve the reference to variable x used in file2.c.
References:
http://en.wikipedia.org/wiki/Translation_unit_(programming)
http://en.wikipedia.org/wiki/Call_stack
A static variable value persists between different function calls andits scope is limited to the local block
a static var always initializes with value 0
There are 2 cases:
(1) Local variables declared static: Allocated in data segment instead of stack. Its value retains when you call the function again.
(2) Global variables or functions declared static: Invisible outside compilation unit (i.e. are local symbols in symbol table during linking).
Static variables have a property of preserving their value even after they are out of their scope!Hence, static variables preserve their previous value in their previous scope and are not initialized again in the new scope.
Look at this for example -
A static int variable remains in memory while the program is running. A normal or auto variable is destroyed when a function call where the variable was declared is over.
#include<stdio.h>
int fun()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("%d ", fun());
printf("%d ", fun());
return 0;
}
This will output: 1 2
As 1 stays in the memory as it was declared static
Static variables (like global variables) are initialized as 0 if not initialized explicitly. For example in the below program, value of x is printed as 0, while value of y is something garbage. See this for more details.
#include <stdio.h>
int main()
{
static int x;
int y;
printf("%d \n %d", x, y);
}
This will output : 0
[some_garbage_value]
These are the major ones I found that weren't explained above for a newbie!
In C programming, static is a reserved keyword which controls both lifetime as well as visibility. If we declare a variable as static inside a function then it will only visible throughout that function. In this usage, this static variable's lifetime will start when a function call and it will destroy after the execution of that function. you can see the following example:
#include<stdio.h>
int counterFunction()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("First Counter Output = %d\n", counterFunction());
printf("Second Counter Output = %d ", counterFunction());
return 0;
}
Above program will give us this Output:
First Counter Output = 1
Second Counter Output = 1
Because as soon as we call the function it will initialize the count = 0. And while we execute the counterFunction it will destroy the count variable.

Why a global variable is defined as static in this C program? [duplicate]

This question already has answers here:
What does "static" mean in C?
(20 answers)
When to use static keyword before global variables?
(8 answers)
Closed 7 years ago.
I'm trying to learn C using this tutorial. There is an example there that the author is tried to learn us what static storage class is.
This is that example :
#include <stdio.h>
/* function declaration */
void func(void);
static int count = 5; /* global variable */
main()
{
while(count--)
{
func();
}
return 0;
}
/* function definition */
void func( void )
{
static int i = 5; /* local static variable */
i++;
printf("i is %d and count is %d\n", i, count);
}
My question is: Why he/she is defined count as static? In the other words, what is the difference between the above program and the following program?
#include <stdio.h>
/* function declaration */
void func(void);
int count = 5; /* global variable */
main()
{
while(count--)
{
func();
}
return 0;
}
/* function definition */
void func( void )
{
static int i = 5; /* local static variable */
i++;
printf("i is %d and count is %d\n", i, count);
}
I mean, when we must use the first program and when we must use the second one?
Defining your count as a global variable or a static one does not matter in your particular example (where each program has only one source file, i.e. one translation unit). But it does matter for i (which, without the static keyword, would become an automatic local variable), since it is declared inside a function. However, it would matter a big lot for any program made of several translation units (linked together to make the executable).
If you define a count global variable in two different translation units (i.e. in foo1.c and foo2.c) the linker would complain against multiple definitions (when you build your foo executable from foo1.o & foo2.o with gcc foo1.o foo2.o -o foo on your Linux system); if you defined a static int count; variable both in foo1.c and in foo2.c it is ok (but then you have two synonymous variables, each having its own address, and each implicitly initialized to 0; IMHO this is often poor taste, because it makes the source code less readable).
As an exception, you can declare without explicitly initializing it a global variable of the same name in two different translation units. The name refers to the same and unique global (initialized to 0).
So having
// in file foo1.c
int globalcount; // a global variable *declaration*
and
// in file foo2.c
int globalcount; // a global variable *declaration*
is the same as having
// in file foo1.c
int globalcount = 0; // a global variable *definition* with initialization
and
// in file foo2.c
extern int globalcount; // an external variable declaration
Actually, that external declaration should usually be in some header file foo.h which gets #include-d by both foo1.c & foo2.c.
Therefore, static variables (of the main program) are also invisible by plugins. Read more about visibility attribute (on Linux) to make a variable visible only by a single plugin or shared library (but not outside it).
Read wikipage on linkers & dynamic linkers then Levine's book linkers and loaders
Practically speaking, I would suggest to use unique names for non-local variables (both global and static ones), for readability and convenience (since it is easy to grep them); but sometimes you might want to have a few static variables with the same name in different compilation units. If you do, I suggest to comment why, and have some consistent naming conventions.
Look for examples in some free software coded in C.
static for a global variable makes it global only to that file (compilation unit). It will not be accessible from other files (compilation units)

What is the purpose of an external static variable?

K&R c page 83 says the following:
The static declaration, applied to an external variable or function, limits the scope of that object to the rest of the source file being compiled. External static thus provides a way to hide names like buf and bufp in the getch-ungetch combination, which must be external so they can be shared, yet which should not be visible to users of getch and ungetch.
How could any external variable be visible in another file without an extern modifier on the variable in the new file anyway? Is there some type of added protection for variables with the static storage class?
What is the purpose of using static on an external variable? Any simple examples?
Edit:
I think I'm confusing people with my question, so I'm going to write it out as code. I'm expanding the idea to include functions as well:
contents of file 1
void somefunc(void);
int x;
int main()
{
....
}
void somefunc(void)
{
....
}
file 2
int x;
void somefunc(void);
void somefunc(void)
{
....
}
Notice that int x and somefunc() in file 1 are not visible in file 2, and vice versa. That is, unless we include an extern modifier on int x and/or somefunc() in either file, the matching function and variable names from the files will be invisible to one another.
Why would we need to put static on one of these variables or functions to prevent the variable or function from being visible in the other file if we already have to knowingly use an extern to make the function or variable visible in the other file?
The code would need to look like this for contents of file 2 to be visible in file 1:
extern void somefunc(void);
extern int x;
int main()
{
....
}
void somefunc(void)
{
....
}
file 2
int x;
void somefunc(void);
void somefunc(void)
{
....
}
There is a difference of terminology between K&R2 and the C Standard.
K&R2 uses the wording external variable for a file-scope variable, and uses the wording external static to specify a file-scope variable declared with the static storage class specifier. In the C Standard the word external is usually reserved for linkage and not for lexical scope.
Quoting what you quoted:
External static thus provides a way to hide names like buf and bufp in the getch-ungetch combination, which must be external so they can be shared, yet which should not be visible to users of getch and ungetch.
It just means that the static variables are not function scoped static variables. They are external to functions but they are static in the file.
Making them static in a file makes them visible to getch and ungetch but not to other functions in other files.
Update, in response to edited question
You said,
Notice that int x and somefunc() in file 1 are not visible in file 2, and vice versa. That is, unless we include an extern modifier on int x and/or somefunc() in either file, the matching function and variable names from the files will be invisible to one another.
That is an erroneous conclusion.
The line
int x;
equivalent to:
extern int x;
int x;
The line
void somefunc(void);
is equivalent to:
extern void somefunc(void);
If you compile the "file 1" and "file 2" and link the resulting object files to create an executable, you will get linker errors to the effect that int x and void somefunc(void) are multiply defined.
In order to keep them visible only in the respective files, you will have to make them static in the file scope.
static int x;
static void somefunc(void);
What are the uses of the keyword static?
This simple question is rarely answered completely. Static has three distinct uses in C:
(a) A variable declared static within the body of a function maintains its value between function invocations.
(b) A variable declared static within a module1, (but outside the body of a function) is accessible by all functions within that module. It is not accessible by functions within any other module. That is, it is a localized global.
(c) Functions declared static within a module may only be called by other functions within that module. That is, the scope of the function is localized to the module within which it is declared.
Most candidates get the first part correct. A reasonable number get the second part correct, while a pitiful number understand answer (c).
From A ‘C’ Test: The 0×10 Best Questions for Would-be Embedded Programmers
Think about such a situation:
If you have three files, file1 and file 2 both have int x, but with different values, then in file3 you have extern int x. How could the compiler know which x you want? That's when you need extern.

Access of static variable from one file to another file

I recently came across the question like how to access a variable which declared static in file1.c to another file2.c?
Is it possible to access static variable?
My understanding about static keyword in C is,
static is "internal linkage", so they are accessible only from one compilation unit - the one where they were defined. Objects declared with internal linkage are private to single module.
As one of my friend suggest me below solution.
In file1.c
#include <stdio.h>
int main()
{
int b=foo();
printf("%d",b);
return 0;
}
in file2.c
static int a=25;
int foo()
{
return a;
}
compiled by gcc file1.c file2.c -o file
If I do above I can access the variable.
So my questions are:
Does the above program violate static variable rules?
If not, why is this so, and is there any other way to access static variable except including file (#include <…>) not like this.
How am I able to access a static variable from another file?
In C, how do I restrict the scope of a global variable to the file in which it's declared?
Correct me if I'm wrong with static variable concept and if any better solutions are available to access static variable?
1) does the above program violate static variable rules?
No you are not vailoting any rules. Here foo function create copy of value of that static variable and used in other file. Its fine.
2) If not why is this so, and is there any other way to access static variable except including file (#include<>) not like this How am I able to access a static variable from another file?
Static variable are only mean to use in that file only.
You can not use that variable making them extern in other files.
Another dirty hack is to get pointer of that static variable and make that as global pointer and making that as extern in another file you can use that static variable.
file1.c
#include<stdio.h>
static int a=25;
int* ptr = &a;
file2.c
#include<stdio.h>
extern int *ptr;
int main()
{
printf("%d",*ptr);
return 0;
}
Correct me if I'm wrong with static variable concept and if any better solutions are available?
A static variable has a lifetime extends across the entire run of the program
If you do not initialize static variable with some value then its default value would be 0.
A static variable has scope limited to its file only. You can not access it by name from a different file.
You have temp1.c and temp2.c both are getting compiled together then also you can have static variable of same name in both files — and they are separate variables.
In C, how do I restrict the scope of a global variable to the file in which it's declared?
By making that global variable as static.
What we commonly call a variable in C is actually two things: an object, the memory allocated for the variable interpreted with a certain type, and an identifier, one way to access that object.
There is no problem in accessing a static object or its value from another compilation unit. Your function foo promotes the value to another unit, that is fine, but it could even promote the address of a without problems.
Having internal linkage only concerns the identifer, the name a. This one is only visible inside file2.c.
With the static int a=25; the variable a will have internal linkage; meaning the linker cannot see a anywhere outside of the file2.c TU.
When you're calling foo() in file2.c, you get a copy of a, it's the copy that you print; but this doesn't mean you have access to the actual a defined in file2.c When you need such an access where the same variable is visible across different TUs, you could do this
Defining file
This file both declares and defines the variable; additionally initializes it to 1 too, without which it'll be default initialized to 0.
// (non-static) global variable with external linkage and thus visible across TUs
int var_across = 0;
void use()
{
var_across = 1;
}
Using file
// just a declaration to tell that it's defined elsewhere; not a definition
extern int var_across;
void use_here()
{
var_across = 2;
}
Assigning address of static variable to pointer will make static variable available to subfiles.
In subfiles we have to use extern keyword to the pointer.
But it is not necessary to do that.

What does "static" mean in C?

I've seen the word static used in different places in C code; is this like a static function/class in C# (where the implementation is shared across objects)?
A static variable inside a function keeps its value between invocations.
A static global variable or a function is "seen" only in the file it's declared in
(1) is the more foreign topic if you're a newbie, so here's an example:
#include <stdio.h>
void foo()
{
int a = 10;
static int sa = 10;
a += 5;
sa += 5;
printf("a = %d, sa = %d\n", a, sa);
}
int main()
{
int i;
for (i = 0; i < 10; ++i)
foo();
}
This prints:
a = 15, sa = 15
a = 15, sa = 20
a = 15, sa = 25
a = 15, sa = 30
a = 15, sa = 35
a = 15, sa = 40
a = 15, sa = 45
a = 15, sa = 50
a = 15, sa = 55
a = 15, sa = 60
This is useful for cases where a function needs to keep some state between invocations, and you don't want to use global variables. Beware, however, this feature should be used very sparingly - it makes your code not thread-safe and harder to understand.
(2) Is used widely as an "access control" feature. If you have a .c file implementing some functionality, it usually exposes only a few "public" functions to users. The rest of its functions should be made static, so that the user won't be able to access them. This is encapsulation, a good practice.
Quoting Wikipedia:
In the C programming language, static
is used with global variables and
functions to set their scope to the
containing file. In local variables,
static is used to store the variable
in the statically allocated memory
instead of the automatically allocated
memory. While the language does not
dictate the implementation of either
type of memory, statically allocated
memory is typically reserved in data
segment of the program at compile
time, while the automatically
allocated memory is normally
implemented as a transient call stack.
And to answer your second question, it's not like in C#.
In C++, however, static is also used to define class attributes (shared between all objects of the same class) and methods. In C there are no classes, so this feature is irrelevant.
There is one more use not covered here, and that is as part of an array type declaration as an argument to a function:
int someFunction(char arg[static 10])
{
...
}
In this context, this specifies that arguments passed to this function must be an array of type char with at least 10 elements in it. For more info see my question here.
Short answer ... it depends.
Static defined local variables do not lose their value between function calls. In other words they are global variables, but scoped to the local function they are defined in.
Static global variables are not visible outside of the C file they are defined in.
Static functions are not visible outside of the C file they are defined in.
Multi-file variable scope example
Here I illustrate how static affects the scope of function definitions across multiple files.
a.c
#include <stdio.h>
/*
Undefined behavior: already defined in main.
Binutils 2.24 gives an error and refuses to link.
https://stackoverflow.com/questions/27667277/why-does-borland-compile-with-multiple-definitions-of-same-object-in-different-c
*/
/*int i = 0;*/
/* Works in GCC as an extension: https://stackoverflow.com/a/3692486/895245 */
/*int i;*/
/* OK: extern. Will use the one in main. */
extern int i;
/* OK: only visible to this file. */
static int si = 0;
void a() {
i++;
si++;
puts("a()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
main.c
#include <stdio.h>
int i = 0;
static int si = 0;
void a();
void m() {
i++;
si++;
puts("m()");
printf("i = %d\n", i);
printf("si = %d\n", si);
puts("");
}
int main() {
m();
m();
a();
a();
return 0;
}
GitHub upstream.
Compile and run:
gcc -c a.c -o a.o
gcc -c main.c -o main.o
gcc -o main main.o a.o
Output:
m()
i = 1
si = 1
m()
i = 2
si = 2
a()
i = 3
si = 1
a()
i = 4
si = 2
Interpretation
there are two separate variables for si, one for each file
there is a single shared variable for i
As usual, the smaller the scope, the better, so always declare variables static if you can.
In C programming, files are often used to represent "classes", and static variables represent private static members of the class.
What standards say about it
C99 N1256 draft 6.7.1 "Storage-class specifiers" says that static is a "storage-class specifier".
6.2.2/3 "Linkages of identifiers" says static implies internal linkage:
If the declaration of a file scope identifier for an object or a function contains the storage-class specifier static, the identifier has internal linkage.
and 6.2.2/2 says that internal linkage behaves like in our example:
In the set of translation units and libraries that constitutes an entire program, each declaration of a particular identifier with external linkage denotes the same object or function. Within one translation unit, each declaration of an identifier with internal linkage denotes the same object or function.
where "translation unit is a source file after preprocessing.
How GCC implements it for ELF (Linux)?
With the STB_LOCAL binding.
If we compile:
int i = 0;
static int si = 0;
and disassemble the symbol table with:
readelf -s main.o
the output contains:
Num: Value Size Type Bind Vis Ndx Name
5: 0000000000000004 4 OBJECT LOCAL DEFAULT 4 si
10: 0000000000000000 4 OBJECT GLOBAL DEFAULT 4 i
so the binding is the only significant difference between them. Value is just their offset into the .bss section, so we expect it to differ.
STB_LOCAL is documented on the ELF spec at http://www.sco.com/developers/gabi/2003-12-17/ch4.symtab.html:
STB_LOCAL Local symbols are not visible outside the object file containing their definition. Local symbols of the same name may exist in multiple files without interfering with each other
which makes it a perfect choice to represent static.
Variables without static are STB_GLOBAL, and the spec says:
When the link editor combines several relocatable object files, it does not allow multiple definitions of STB_GLOBAL symbols with the same name.
which is coherent with the link errors on multiple non static definitions.
If we crank up the optimization with -O3, the si symbol is removed entirely from the symbol table: it cannot be used from outside anyways. TODO why keep static variables on the symbol table at all when there is no optimization? Can they be used for anything? Maybe for debugging.
See also
analogous for static functions: https://stackoverflow.com/a/30319812/895245
compare static with extern, which does "the opposite": How do I use extern to share variables between source files?
C++ anonymous namespaces
In C++, you might want to use anonymous namespaces instead of static, which achieves a similar effect, but further hides type definitions: Unnamed/anonymous namespaces vs. static functions
It depends:
int foo()
{
static int x;
return ++x;
}
The function would return 1, 2, 3, etc. --- the variable is not on the stack.
a.c:
static int foo()
{
}
It means that this function has scope only in this file. So a.c and b.c can have different foo()s, and foo is not exposed to shared objects. So if you defined foo in a.c you couldn't access it from b.c or from any other places.
In most C libraries all "private" functions are static and most "public" are not.
People keep saying that 'static' in C has two meanings. I offer an alternate way of viewing it that gives it a single meaning:
Applying 'static' to an item forces that item to have two properties: (a) It is not visible outside the current scope; (b) It is persistent.
The reason it seems to have two meanings is that, in C, every item to which 'static' may be applied already has one of these two properties, so it seems as if that particular usage only involves the other.
For example, consider variables. Variables declared outside of functions already have persistence (in the data segment), so applying 'static' can only make them not visible outside the current scope (compilation unit). Contrariwise, variables declared inside of functions already have non-visibility outside the current scope (function), so applying 'static' can only make them persistent.
Applying 'static' to functions is just like applying it to global variables - code is necessarily persistent (at least within the language), so only visibility can be altered.
NOTE: These comments only apply to C. In C++, applying 'static' to class methods is truly giving the keyword a different meaning. Similarly for the C99 array-argument extension.
static means different things in different contexts.
You can declare a static variable in a C function. This variable is only visible in the function however it behaves like a global in that it is only initialized once and it retains its value. In this example, everytime you call foo() it will print an increasing number. The static variable is initialized only once.
void foo ()
{
static int i = 0;
printf("%d", i); i++
}
Another use of static is when you implement a function or global variable in a .c file but don't want its symbol to be visible outside of the .obj generated by the file. e.g.
static void foo() { ... }
From Wikipedia:
In the C programming language, static is used with global variables and functions to set their scope to the containing file. In local variables, static is used to store the variable in the statically allocated memory instead of the automatically allocated memory. While the language does not dictate the implementation of either type of memory, statically allocated memory is typically reserved in data segment of the program at compile time, while the automatically allocated memory is normally implemented as a transient call stack.
I hate to answer an old question, but I don't think anybody has mentioned how K&R explain it in section A4.1 of "The C Programming Language".
In short, the word static is used with two meanings:
Static is one of the two storage classes (the other being
automatic). A static object keeps its value between invocations. The objects declared outside all blocks are always static and cannot be made automatic.
But, when the static keyword (big emphasis on it being used in
code as a keyword) is used with a declaration, it gives that object internal linkage so it can only be used within that translation unit. But if the keyword is used in a function, it changes the storage class of the object (the object would only be visible within that function anyway). The opposite of static is the extern keyword, which gives an object external linkage.
Peter Van Der Linden gives these two meanings in "Expert C Programming":
Inside a function, retains its value between calls.
At the function level, visible only in this file.
If you declare a variable in a function static, its value will not be stored on the function call stack and will still be available when you call the function again.
If you declare a global variable static, its scope will be restricted to within the file in which you declared it. This is slightly safer than a regular global which can be read and modified throughout your entire program.
A static variable is a special variable that you can use in a function, and it saves the data between calls, and it does not delete it between calls. For example:
void func(void) {
static int count; // If you don't declare its value, it is initialized with zero
printf("%d, ", count);
++count;
}
int main(void) {
while(true) {
func();
}
return 0;
}
The output:
0, 1, 2, 3, 4, 5, ...
In C, static has two meanings, depending on scope of its use. In the global scope, when an object is declared at the file level, it means that that object is only visible within that file.
At any other scope it declares an object that will retain its value between the different times that the particular scope is entered. For example, if an int is delcared within a procedure:
void procedure(void)
{
static int i = 0;
i++;
}
the value of 'i' is initialized to zero on the first call to the procedure, and the value is retained each subsequent time the procedure is called. if 'i' were printed it would output a sequence of 0, 1, 2, 3, ...
If you declare this in a mytest.c file:
static int my_variable;
Then this variable can only be seen from this file. The variable cannot be exported anywhere else.
If you declare inside a function the value of the variable will keep its value each time the function is called.
A static function cannot be exported from outside the file. So in a *.c file, you are hiding the functions and the variables if you declare them static.
Share what I learned about this point.
In C static is a declaration specifier, which falls into three categories:
storage classes: there are four classes: auto, static, extern and register.
type qualifiers: like keywords: const, volatile, etc.
type specifiers: like keywords: void, char, short, int, etc.
So static is a storage classes. It will determine the following three properties of each variable in a C program.
storage duration: means when memory is allocated for the variable and when the memory is released. A variable with static storage duration stays at the same memory location as long as the program is running.
scope: means the portion of the program text in which the variable can be accessed. A static variable has a file scope instead of a block scope.
linkage: means the extent to which the variable can be shared by different parts(or files) of a program. If a static variable is declared inside a block then it has no linkage. If a static variable is declared outside blocks, then it has internal linkage. Internal linkage makes it accessible in a single file.
The static storage class has a different effect on a variable depending on it is declared outside a block or inside a block. Need to consider case by case.
It is important to note that static variables in functions get initialized at the first entry into that function and persist even after their call has been finished; in case of recursive functions the static variable gets initialized only once and persists as well over all recursive calls and even after the call of the function has been finished.
If the variable has been created outside a function, it means that the programmer is only able to use the variable in the source-file the variable has been declared.
Static variables in C have the lifetime of the program.
If defined in a function, they have local scope, i.e. they can be accessed only inside those functions. The value of static variables is preserved between function calls.
For example:
void function()
{
static int var = 1;
var++;
printf("%d", var);
}
int main()
{
function(); // Call 1
function(); // Call 2
}
In the above program, var is stored in the data segment. Its lifetime is the whole C program.
After function call 1, var becomes 2. After function call 2, var becomes 3.
The value of var is not destroyed between functions calls.
If var had between non static and local variable, it would be stored in the stack segment in the C program. Since the stack frame of the function is destroyed after the function returns, the value of var is also destroyed.
Initialized static variables are stored in the data segment of the C program whereas uninitialized ones are stored in the BSS segment.
Another information about static: If a variable is global and static, it has the life time of the C program, but it has file scope. It is visible only in that file.
To try this:
file1.c
static int x;
int main()
{
printf("Accessing in same file%d", x):
}
file2.c
extern int x;
func()
{
printf("accessing in different file %d",x); // Not allowed, x has the file scope of file1.c
}
run gcc -c file1.c
gcc -c file2.c
Now try to link them using:
gcc -o output file1.o file2.o
It would give a linker error as x has the file scope of file1.c and the linker would not be able to resolve the reference to variable x used in file2.c.
References:
http://en.wikipedia.org/wiki/Translation_unit_(programming)
http://en.wikipedia.org/wiki/Call_stack
A static variable value persists between different function calls andits scope is limited to the local block
a static var always initializes with value 0
There are 2 cases:
(1) Local variables declared static: Allocated in data segment instead of stack. Its value retains when you call the function again.
(2) Global variables or functions declared static: Invisible outside compilation unit (i.e. are local symbols in symbol table during linking).
Static variables have a property of preserving their value even after they are out of their scope!Hence, static variables preserve their previous value in their previous scope and are not initialized again in the new scope.
Look at this for example -
A static int variable remains in memory while the program is running. A normal or auto variable is destroyed when a function call where the variable was declared is over.
#include<stdio.h>
int fun()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("%d ", fun());
printf("%d ", fun());
return 0;
}
This will output: 1 2
As 1 stays in the memory as it was declared static
Static variables (like global variables) are initialized as 0 if not initialized explicitly. For example in the below program, value of x is printed as 0, while value of y is something garbage. See this for more details.
#include <stdio.h>
int main()
{
static int x;
int y;
printf("%d \n %d", x, y);
}
This will output : 0
[some_garbage_value]
These are the major ones I found that weren't explained above for a newbie!
In C programming, static is a reserved keyword which controls both lifetime as well as visibility. If we declare a variable as static inside a function then it will only visible throughout that function. In this usage, this static variable's lifetime will start when a function call and it will destroy after the execution of that function. you can see the following example:
#include<stdio.h>
int counterFunction()
{
static int count = 0;
count++;
return count;
}
int main()
{
printf("First Counter Output = %d\n", counterFunction());
printf("Second Counter Output = %d ", counterFunction());
return 0;
}
Above program will give us this Output:
First Counter Output = 1
Second Counter Output = 1
Because as soon as we call the function it will initialize the count = 0. And while we execute the counterFunction it will destroy the count variable.

Resources