This item was added on: 2011/11/15
The extern and static (1) keywords seem to cause more confusion than they should. They are both storage-class specifiers, more specifically linkage specifiers. Linkage is a concept that tells the compiler what to do when two files declare an object or function with the same name. Of course, this only applies to "file level" identifiers, i.e. functions and global variables. It does not apply to function parameters or local function variables, since those are only visible from within that function.
The extern keyword specifies external linkage. It tells the compiler that the object or function declared here is actually defined in another file. It helps here to explain the difference between definition and declaration. Definition is where the variable is created and space is set aside for it. For functions, the definition is the function body. Declaration is simply stating the linkage and type of the variable, so the compiler can ensure you're using it correctly. For functions, the declaration states the linkage, return type, parameter count and parameter types. Go here for more on the difference between declare and define in C and C++.
The static keyword is somewhat the opposite of extern. It tells the compiler that the object or function declared is internally linked, and only visible from within that translation unit (a translation unit is a technical term for a .c file after all the preprocessing is finished and the #includes added in).
extern should be used in a header file to make functions available to other .c files that wish to use that interface. This makes them akin to public members in a C++ class. static should be used in the .c file with the variable and function definitions, to hide functions and variables from other .c files. This is akin to private members in a C++ class.
As you can tell, it makes no sense to have something declared as static and again as extern. Doing so results in undefined behavior, so don't do it!
Here is an example program demonstrating the use of static and extern:
extern void foo(void); // make function 'foo' visible to other .c files
#endif // FOO_H__
static void bar(void)
puts("I'm bar(), and I can only be called from within foo.c");
puts("I'm foo(), and I can be called from any file that includes foo.h");
Compiling and running:
$ gcc -Wall foo.c main.c -o foo
I'm foo(), and I can be called from any file that includes foo.h
I'm bar(), and I can only be called from within foo.c
(1) static seems to be a poorly chosen keyword for specifying linkage, and has confused many, if not all C programmers at some point (it's choice for describing storage duration, however, is excellent). There is nothing particularly static about something with internal (static) linkage. They don't stay in one place any more than their non-static counterparts. A more appropriate choice might have been intern(al) or private, but it's too late now.