Okay to declare static global variable in .h file?

Viewed 23900

static keyword keeps the scope of a global variable limited to that translation unit. If I use static int x in a .h file and include that .h file every other file, won't they all belong to the same translation unit? Then, won't x be visible everywhere? So what is the role of static now?

Also, is there any use of static const int x ,where x is a global variable? Aren't all const global variables static by default? And is a const variable's scope limited to the TU even if it confined in a for loop in the file?

6 Answers

"static global" doesn't make sense, they are in a way each other's opposites.

The term "global" is often misused to describe a variable declared outside any function at file scope. But rather, a global variable is one with external linkage, that can be accessed by any file in the project - hence global.

The opposite of external linkage is internal linkage, which means that a variable can only get accessed by the translation unit where it is declared. Translation unit meaning one .c file and all the headers included by it (recursively).

static is a guarantee that a variable gets internal linkage. Thus other translation will not be able to access it or declare extern variables referring to it.

What happens if you declare a static variable in a header file is that more than one translation unit will get a separate variable with that name. The code will compile fine, although clever linkers will notice this and give a linker error. These kind of linker errors are often non-descriptive and hard to track down.

This leads us to the following best practices:

  • Never declare any variables inside a header file, as this often creates subtle bugs and linker errors.
  • To prevent such bugs, always surround all header files with "header guards":

    #ifndef MYHEADER_H 
    #define MYHEADER_H 
      /* contents of header */ 
    #endif
    
  • All variables declared at file scope should be declared static, for the purpose of private encapsulation and to reduce namespace clutter. Similarly, extern should be avoided, as it leads to bad design and spaghetti programming.

Related