Reasons to use Static functions and variables in C

Gauthier picture Gauthier · Jun 4, 2010 · Viewed 23k times · Source

I wonder about the use of the static keyword as scope limiting for variables in a file, in C.

The standard way to build a C program as I see it is to:

  • have a bunch of c files defining functions and variables, possibly scope limited with static.
  • have a bunch of h files declaring the functions and possibly variables of the corresponding c file, for other c files to use. Private functions and variables are not published in the h file.
  • every c file is compiled separately to an o file.
  • all o files are linked together to an application file.

I see two reasons for declaring a gobal as static, if the variable is not published in the h file anyway:

  • one is for readability. Inform future readers including myself that a variable is not accessed in any other file.
  • the second is to prevent another c file from redeclaring the variable as extern. I suppose that the linker would dislike a variable being both extern and static. (I dislike the idea of a file redeclaring a variable owned by someone else as extern, is it ok practice?)

Any other reason?

Same goes for static functions. If the prototype is not published in the h file, other files may not use the function anyway, so why define it static at all? I can see the same two reasons, but no more.

Answer

crazyscot picture crazyscot · Jun 4, 2010

When you talk about informing other readers, consider the compiler itself as a reader. If a variable is declared static, that can affect the degree to which optimizations kick in.

Redefining a static variable as extern is impossible, but the compiler will (as usual) give you enough rope to hang yourself.

If I write static int foo; in one file and int foo; in another, they are considered different variables, despite having the same name and type - the compiler will not complain but you will probably get very confused later trying to read and/or debug the code. (If I write extern int foo; in the second case, that will fail to link unless I declare a non-static int foo; somewhere else.)

Global variables rarely appear in header files, but when they do they should be declared extern. If not, depending on your compiler, you risk that every source file which includes that header will declare its own copy of the variable: at best this will cause a link failure (multiply-defined symbol) and at worst several confusing cases of overshadowing.