A Basic C Program Using Global Variables
Let's take a trip back in time (before OOP was mainstream) and see how the use of data within code has evolved. Remember that modern languages such as Java and .NET are object-oriented (OO) languages, born after 1995. So our conversation starts way back in the day when the C programming language ruled the world (along with COBOL and FORTRAN, of course). C is the ancestor of C++, Java, JavaScript, C#, and many other languages—this is truly a process of evolution.
We can jump right into some code (Listing 1) and show a typical C program that utilizes global variables. Here we have a very primitive application that contains the requisite main() entry point, as well as a function to process a hypothetical drivers license. Please be aware that we're using integers in these examples.
Listing 1Basic C program.
// License01.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <iostream> // Function Prototypes void driversLicense(); // Global Variable int age = 0; int main() { driversLicense(); printf("age = %d\n", age); system("pause"); return 0; } // driversLicense.c // #include "stdafx.h" #include<stdio.h> void driversLicense() { age = 16; }
The important point to consider when looking at the code in Listing 1 is that absolutely no attempt is made to control access to the data. A single copy of the variable age is shared application-wide by all functions. The definition and declaration of the variable is outside the scope of the functions and is of global scope. As a result, any function that is part of this application can gain unfettered access to this variable (read and modify) simply by including this line:
extern int age;
While this solution seems elegant, it can be dangerous.
I have to admit that when I first started programming in C and C++, I often used global variables, which made implementing code much easier—although not necessarily better. At times I honestly believed certain solutions required the use of global variables. In reality, indiscriminately using global variables makes code difficult to read; complex to maintain; prone to bugs; and, perhaps most ominously, vulnerable to malicious intent.
For example, let's say that 20 different functions within the application can actually modify the value of age. Now suppose that a bug is identified, and we determine that age has somehow been set to an invalid value. With 20 different locations that can modify age, which one is the culprit? This is a quality assurance (QA) and maintenance nightmare. Just consider if the code contained 100 possible modification points—or more!