C Globals – Are File-Scope Static Variables as Bad as Extern Global Variables?

cglobals

In C, you'd often/sometimes (as a matter of style) use a file-scope static variable where you'd use a private class member variable in C++. When scaling to multithreaded programs, simply adding thread_local in C11 or the long-supported extension __thread fits well. I know you can do exactly the same in C as C++ by putting everything inside a struct and making a set of functions that takes a pointer to that struct as its first argument. Some libraries do this extensively. But my personal style is to keep a struct as small as possible, if needed.

I often read or hear some people arguing 'global' variables are so much bad. I follow their reasons, and most of their argument seems to be related to extern global variables in C terms. What they say is certainly true. I sometimes use 1 or 2 of extern declared variables throughout the whole program when it'll simplify things a lot and when it's easy to keep track of them, but going further will easily make a program unpredictable.

What about static variables? Do they still have the same problem as 'real' global variables? Maybe I don't even have to ask this question and go on if I think what I'm doing is right, but today I saw another 'global variables are BAD' kind of post, and finally came here thinking perhaps this is a right place for such kind of question. What is your thought?

This question is not a duplicate of this because this question asks about extern and static non-local variables while the other question is about file-scope and block-scope static variables.

Best Answer

In a well-design C program, a file-static variable is similar to a private static member of a class:

  • It can only be accessed by functions in that file, similar to how a private static member variable can only be accessed by functions in the class in which it is defined.

  • There is only one copy of the variable.

  • Its lifetime is the program lifetime.

An extern variable would be a true global variable as in any language that supports them.

A static non-global variable is not as bad as a global; in fact, they are necessary in some cases.

  • Access is controlled through functions you write. This helps with data integrity including both bounds checking as well as thread-safety. (note: this does not guarantee thread-safety, it is simply one tool to help along the way)

  • Data is encapsulated: only that file can access it. This is as close as C can get to encapsulation where multiple functions can access a static variable.

Global variables are bad no matter what. Static file variables have the benefits of a private static variable but none of the drawbacks of a global variable.

The only issue is unlike with a true private static variable as in C++, other files can declare an extern variable matching the declaration and you cannot prevent access. In other words, you are relying on the honor system to avoid turning it into a global variable.

Related Topic