Why is a global variable defined as static in this program?
I am trying to learn C using this tutorial. There is an example here that the author is trying to find out what static
the storage class is.
This is an 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 is he / she defined count
as static
? In 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 should we use the first program and when should we use the second?
Defining yours count
as a global variable or static
is irrelevant in your specific example (where each program only has one source file, i.e. one translation unit ). But it matters to i
(which without the keyword static
will become an automatic local variable) as it is declared inside the function. However, this will make a big difference for any program that has multiple translation units (linked together to create an executable file).
If you define a global variable count
in two different translation units (for example, in foo1.c
and foo2.c
), the linker will complain about multiple definitions (when you create your foo
executable from foo1.o
and foo2.o
with gcc foo1.o foo2.o -o foo
on your Linux system); if you have defined a variable in static int count;
both in foo1.c
and in foo2.c
, that's ok (but then you have two synonymous variables, each with its own address and each implicitly initialized to 0; IMHO this is often bad taste because it makes the source code less readable).
As an exception, you can declare, without explicitly initializing, a global variable with 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*
coincides with
// 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, this external declaration should usually be in some kind of header file foo.h
that receives #include
both -d foo1.c
and foo2.c
.
Therefore static variables (of the main program) are also invisible by plugins . Learn more about the visibility attribute (on Linux) to make a variable visible to only one plugin or shared library (but not outside of it).
Read the wikipage on linkers and dynamic linkers , then Levine's book linkers and loaders
In practice, I would suggest using unique names for non-local variables (both global and static), for readability and convenience (since it's easy grep
); but sometimes you may need multiple variables static
with the same name in different compilation units. If you do, I suggest commenting on why, and have some consistent naming conventions.
source to share