Reputation: 471
I'm learning C and came across this program.
#include <stdio.h>
int a, b, c = 0;
void prtFun (void);
int main ()
{
static int a = 1; /* line 1 */
prtFun();
a += 1;
prtFun();
printf ( "n %d %d " , a, b) ;
}
void prtFun (void)
{
static int a = 2; /* line 2 */
int b = 1;
a += ++b;
printf (" n %d %d " , a, b);
}
The output is as follows:
4 2
6 2
2 0
It gives the following explanation
"‘a’ and ‘b’ are global variable. prtFun() also has ‘a’ and ‘b’ as local variables. The local variables hide the globals (See Scope rules in C). When prtFun() is called first time, the local ‘b’ becomes 2 and local ‘a’ becomes 4. When prtFun() is called second time, same instance of local static ‘a’ is used and a new instance of ‘b’ is created because ‘a’ is static and ‘b’ is non-static. So ‘b’ becomes 2 again and ‘a’ becomes 6. main() also has its own local static variable named ‘a’ that hides the global ‘a’ in main. The printf() statement in main() accesses the local ‘a’ and prints its value. The same printf() statement accesses the global ‘b’ as there is no local variable named ‘b’ in main. Also, the defaut value of static and global int variables is 0. That is why the printf statement in main() prints 0 as value of b."
I was under the impression that static variables in C are declared only once and have a global scope and also that all global variables were implicitly static. So how is it correct that you can redeclare these static variables in different scopes given the global scope of either the implicit declaration of the global variables or the explicit declaration in main? If there is only one place in memory for a static variable and it has a global scope how are there block specific static variables in this program with the same name?
Thanks
Upvotes: 2
Views: 241
Reputation: 628
I'll try to help you by being as concise as I can. The following statements are simply not true in C:
Global variables can be static or non-static (regular). The difference is that regular global variables can be used by other translation units (briefly, C files), while the static variables cannot.
Let me give you an example. Let's say you have two C files, a.c and b.c. In a.c:
int my_global_var;
static int a_static_var;
In b.c:
extern int my_global_var;
static int a_static_var;
int main() { /* ... */ }
You can build a program using both the C files, this way [assuming you're using Linux]:
gcc -c a.c
gcc -c b.c
gcc -o prog a.o b.o
Now, the variable my_global_var
is the same in both the files, but it is instantiated in the a.o
translation unit (b.c sees it as an extern variable). While the variable a_static_var
is not unique. Each translation unit has its own a_static_var
variable: they are completely unrelated.
Returning back to your example, static variables can also have function scope: in that case, static variables defined inside different functions are completely unrelated, the same way as global static variables inside separate translation units are unrelated. In your case you can think about the two static a
variables AS IF they were called __main_a
and __prtFun_b
. That's actually pretty close to what happens under the hood, when you compile your program.
Now, to complete the picture there is a rule allowing you to define local (static or not) variables, even when that will hide global variables defined with the same name. Therefore, in prtFun()
for example, when you access b
, you're accessing your local non-static variable and when you access a
, you're accessing your local static a
variable. The same is true for main()
. In no case your code touches the global a, b, c
variables.
I hope I've been helpful.
Upvotes: 6
Reputation: 690
Even though vvaltchev has already provided a good explanation, i would like to add a thing or two...
Most books, tutorials, etc. use static as demonstrated in your code, to preserve the value of a local variable over multiple function calls. This, however is only one of the uses for static, and - in my opinion - the more useless one.
Let's revisit this statement
Global variables can be static or non-static (regular). The difference is that regular global variables can be used by other translation units (briefly, C files), while the static variables cannot.
This usage of static is not demonstrated in your code, but is really, really useful, because it essentially means that you can define variables (and functions!) which are "private", and will never be visible from another c file. This allows to cleanly separate, which functions and variables should be visible from other modules, and which ones should not.
I strongly recommend to define ALL functions as static, which should not be called from inside another c file.
I feel that this aspect of static is overlooked way too often, and everyone seems to just focus on the stupid "hey you can preserve that value over multiple function calls". Even though that often is a really bad idea, because then you have a function which behaves differently each time you call it.
Upvotes: 1