Minimizing variable scope

Recall that programming is about communication with the maintainer of the code, more than about communication with the compiler.

In order to help the maintainer as much as possible, we should make sure variables and other identifiers have as small a scope as possible.

The scope of a variable is the physical program text in which it is visible. The smaller to scope of each variable, the fewer the live variables at any particular point in the code.

Declaring variables static

One easy way to minimize the scope of a variable is to define it `static' at the top level of a file. A variable defined at the top level of a file without the static keyword is completely global in the program, accessible to all code in all files. So for instance if in one file (say a.c we have the following definition:
	int myvar;
we can do the following in another file (say b.c):
	extern int myvar;
which gives all the code in b.c access to the global variable myvar in a.c. A reader of the code in a.c must know all the places in all the files in order to understand all possibilities in which myvar can be used and modified. Such totally global variables should be avoided if possible. But if the intent of myvar was for it to be used only in a.c we can help the maintainer by making the following modification:
	static int myvar;
Now, myvar is accessible only to code in a.c. The maintainer knows that he or she does not have to look elsewhere because of the keyword `static'.

The same thing is true for functions. A function meant to be used only from other functions in a particular file can be declared `static' like this:

	static int
	myfun(int x)
	{
	  ...
	}
[see `indentation' for an explanation as to the newline between `int' and `myfun']

Now, myfun can only be used from other functions in the same file a.c.

Using local variables

For variables that are to be used only in one function, it is even better to define them locally in that function. For instance, instead of this:
	static int i;

	int
	myfun(int n)
	{
	  for(i = 0; i < n; i++)
	  ...
	}
It is much better to define the variable `i' locally inside myfun like this:
	int
	myfun(int n)
	{
	  int i;
	  for(i = 0; i < n; i++)
	  ...
	}
Notice that you don't use the word `static' in this case, which means something different for local variables.

Even if the same variable is used in several functions, it is better practice to use local definitions. Avoid this:

	static int i;
	
	int
	myfun1(int n)
	{
	  for(i = 0; i < n; i++)
	  ...
	}
	
	int
	myfun2(int n)
	{
	  for(i = 0; i < n; i++)
	  ...
	}
Use this instead:
	int
	myfun1(int n)
	{
	  int i;
	  for(i = 0; i < n; i++)
	  ...
	}
	
	int
	myfun2(int n)
	{
	  int i;
	  for(i = 0; i < n; i++)
	  ...
	}
In fact, statically defined variables should only be used when values need to be passed between different functions in a file called at different times. Such situations are relatively rare.

Using variables local to a block

It is possible to restrict the scope of a variable even further. The C language allows variables to be defined in inner blocks (delimited by braces) as well as in functions. A typical example is a nested loop with two different loop variables. One usually sees something like this:
	int f(int m, int n)
	{
	  int i, j;
	  for(i = 0; i < m; i++)
	   {
	     ...
	     for(j = 0; j < n; j++)
	      {
	        ...
	      }
	     ...
	   }
	  ...
	}
But here, the scope of the variable `j' (assuming it is used only as a loop counter in the inner loop) is much greater than it needs to be. We can effectively limit the scope of `j' like this:
	int f(int m, int n)
	{
	  int i;
	  for(i = 0; i < m; i++)
	   {
	     int j;
	     ...
	     for(j = 0; j < n; j++)
	      {
	        ...
	      }
	     ...
	   }
	  ...
	}
Some people wrongly believe that the second version is slower than the first. This is not the case (except possible with a very naive compiler). All reasonable compilers would generate very similar code for the two cases.

If no inner block exists, we can even create one for the sole purpose of limiting the scope of a variable. We frequently see this kind of code:

	int f(int n)
	{
	  int i;
	  ...
	  /* a lot of code that does not use i */
	  ...
	  for(i = 0; i < n; i++)
	   {
	     ...
	   }
	}
Here, the variable `i' is visible in the long code that does not use it. Instead we can do this:
	int f(int n)
	{
	  ...
	  /* a lot of code that does not use i */
	  ...
	  {
	    int i;
	    for(i = 0; i < n; i++)
	     {
	       ...
	     }
	  }
	}
Here, we opened a new block for the sole purpose of limiting the scope of the variable `i'.