Global variables

Here’s an answer I gave on Stack Overflow to someone asking when it’s OK to use global variables.

Here’s a cheap way to get rid of all global variables: put all your code in one big fat class and change the global variables to member variables. Nothing has changed as far as the maintainability of your code, but technically it no longer has global variables.

It’s better to talk about size of scope than whether or not something is global. “Global” just means maximum scope. Instead of saying “global variables are bad,” I think it’s more helpful to say “minimize variable scope.”

A global variable in a 100-line program has a scope of 100 lines. But a member variable in a 1000-line class has a scope of 1000 lines. The latter may be worse.

13 thoughts on “Global variables

  1. Good answer.
    I’d add: in addition to trying to minimize the scope of variables, you should also work on minimizing the number of variables to begin with (like, leveraging functional language features).

  2. I think you hit the nail on the head with “minimize variable scope”.

    One double-edged aspect of good IDEs is that they are good at following variables. This makes it easier to trace global or member variable usage, but that ease makes it less painful to develop with them. Same thing for plain old large scope variables. If you never have to try to trace the variables without a smart IDE, the disadvantages of coding that way are not as apparent.

  3. Christopher Allen-Poole

    ABSOLUTELY. We all could take a lesson from the Lispers and learn to avoid side effects if possible. Learn to hate the stateful class.

    I once heard a lecture which made the point that we’ve drifted far from the original idea of OOP, why? Because we have included states in our objects, making many of them overly-bound data objects without a clear separation of concerns.

    Now, in some cases it is necessary to have both — a program without side effects won’t do much — but I wish it were more widely believed.

  4. Hey, that’s basically how JQuery dealt with the “whaddaya mean, I can’t have a variable called “$”!?!” complaint.

  5. The “cheap” shot is often (not always) a good starting point. The external operation can be largely maintained, or at least eveolved under better control, while the scope-reducing activity can be carried out by a series of refactorings drawn mostly from the set whose names start with “Extract”. I have to admit to being perversely drawn to such tasks…

  6. Good point. Put this way it becomes more obvious that this is just a corollary to keeping coupling low. The bigger the scope of visibility a (mutable, particularly) variable has, the more opportunities there are for bad coupling, side effects, and the bugs they invariably bring with them.

  7. Statefulness has little to do with scope. You can have a stateful object, and have it expose minimal state to the outside world. (Typically, you want it to manage its own state transitions, rather than have every Foo, Bar and Baz fiddle with its guts. But then, in general, you don’t want objects twiddling in each others guts.)

  8. Christopher Allen-Poole

    @Mike I tend to disagree. State and scope are very much related. Actually, I would go so far as to say that the scope is the “accessible state”.

  9. I admit I have done something similar, in C. I define a structure containing all my global variables, declare one instance of this structure in main(), then pass a pointer to this instance when calling any functions that need a global variable. Presto! No global variables.

    Moreover, it seems that with my scheme, variables are more local in scope than with your scheme. I have no variables defined outside of functions at all. It’s still a cheat and “bad form” though, isn’t it? Is some goal beyond minimizing scope more to the point?

  10. @Mike, @Christopher
    Maybe state should be discerned into explicit and implicit state at a certain point of the executable code.

    The explicit state is the one that has an explicit representation that can be (partially) accessed by the code at a certain point. This one relates to scope.

    The implicit one is never seen explicitly by the code. It’s in a way the intrinsic state of the whole system. Including the parts of the explicit representation that cannt be seen by the code and the state of the outside world the code interacts with (outside of the von Neumann machine that executes the code). This one has nothing to do with scope.

    Wait aminute… is this the geek philosopher circle?

  11. The next item on the geek philospher circle’s agenda is using the “goto” statement: Venial sin or mortal sin?

    Points for stipulation:

    At the bare metal level, it’s all gotos anyway
    Goto exists in most languages, even modern C-family ones
    Assigned and especially computed gotos are more evil than plain ones
    It has been proven that gotos can always be avoided in modern languages
    … while acknowledging that the existence of a solution does not mean it is practical or even legible.

  12. IMHO the biggest problem with (mutable) global variables is not scope, it is the way they work in a multi-threaded environment.

Comments are closed.