Programming Techniques:Global Variables

From GPWiki

Contents

Global Variables

A global variable is data that is accessible from anywhere in a program. Do not confuse class/module variables with global variables. They have none of the problems of global variables.

Benefits

Data must be global if it is accessed by code in separate blocks, and having separate copies of it is not practical, feasible, or possible. If one block of code changes the value of some data and other blocks of code must see that change, then it may not be possible for each block to have its own copy and the data may need to be global.

Problems

A global variable may be far-removed in terms of time, location, and scope from code that is dependent on it. Multiple blocks of code accessing a global variable are dependent on each other (because of their mutual dependence on the variable), yet the relationship between them is indirect and even further-removed. Determining how multiple blocks of code are interdependent through a global variable can be difficult and error-prone. That makes it more difficult to maintain and debug code using global variables.

The lifetime of a global variable must encompass the lifetimes of all code that depends on it. This is problematic, since whatever controls the lifetime of a global variable must know about the code that accesses it, so that the variable is created before the code needs it. That creates a circular dependency. The typical scenario is that the module containing the global variable must exist before another module can initialize it (perhaps by initializing the module), and the initialization must be done before yet another module can access the global variable.

Global variables increase the complexity of a program by preventing encapsulation. In addition, the state of an object dependent on a global variable is dependent on the state of the global variable, which is not under its control.

It is possible for a function to reference a global variable both directly and via a reference (such as a pointer) at the same time. This is called aliasing and can cause serious problems.

Methods to Reduce the Problems

It is not possible to eliminate global variables entirely, but there are several methods for reducing the problems caused by global variables.

Limiting the Scope

Easily, the most effective way to reduce the problems caused by global variables is to reduce the scope of the variable, making it less global. For example, a variable used by only a single module could be moved to inside the module. A variable used only inside a for-loop, could be moved to inside the for-loop.

The Singleton Pattern

A common misconception is that using the Singleton pattern for a global variable makes it less global. This is not the case; however, it does solve the problem of controlling the lifetime of the global variable. Using a Singleton, the code that creates and initializes the variable does not need to know about the code that uses it, and the code that uses it does not need worry about the lifetime of the variable. This removes a critical (yet indirect) interdependency between two otherwise unrelated blocks of code.

Passing by Parameter

When calling a function, the value of a variable or a reference to a variable can be passed as a parameter. This eliminates the need for the variable to be accessed directly, and removes a dependency.

Restricting Access

Removing the ability to access the internal state of a global variable does not make it less global, but it does reduce the coupling, and it also reduces the coupling between separate blocks of code that are dependent on the global variable.

Avoiding Global Variables

Several uses of global variables are unnecessary -- they can be turned into non-global variables.

  • A variable used in a single scope could exist only in that scope. There is no need for the variable to be global.
  • A global aggregation of data can be split up. The individual elements can be dealt with individually, perhaps reducing their scope. In addition, two blocks of code that depend on two separate elements are no longer interdependent.
  • A global variable containing constant data can be copied. Each scope that accesses it could simply contain its own copy. The drawback is that this is an obvious target for optimization, so its usefulness may be low.