Free Hosting

Global variables


In the last lesson, you learned that variables declared inside a block have block scope. Block scope variables can only be accessed within the block in which they are declared (or a nested sub-block), and are destroyed when the block ends.
Variables declared outside of a block are called global variables. Global variables have program scope, which means they can be accessed everywhere in the program, and they are only destroyed when the program ends.
Here is an example of declaring a global variable:
1
2
3
4
5
6
7
8
9
10
int g_nX; // global variable
 
int main()
{
    int nY; // local variable nY
 
    // global vars can be seen everywhere in program
    // so we can change their values here
    g_nX = 5;
} // nY is destroyed here
Because global variables have program scope, they can be used across multiple files. In the section on programs with multiple files, you learned that in order to use a function declared in another file, you have to use a forward declaration, or a header file.
Similarly, in order to use a global variable that has been declared in another file, you have to use a forward declaration or a header file, along with the extern keyword. Extern tells the compiler that you are not declaring a new variable, but instead referring to a variable declared elsewhere.
Here is an example of using a forward declaration style extern:
global.cpp:
1
2
// declaration of g_nValue
int g_nValue = 5;
main.cpp:
1
2
3
4
5
6
7
8
// extern tells the compiler this variable is declared elsewhere
extern int g_nValue;
 
int main()
{
    g_nValue = 7;
    return 0;
}
Here is an example of using a header file extern:
global.cpp:
1
2
// declaration of g_nValue
int g_nValue = 5;
global.h:
1
2
3
4
5
6
7
#ifndef GLOBAL_H // header guards
#define GLOBAL_H
 
// extern tells the compiler this variable is declared elsewhere
extern int g_nValue;
 
#endif
main.cpp:
1
2
3
4
5
6
#include "global.h"
int main()
{
    g_nValue = 7;
    return 0;
}
Generally speaking, if a global variable is going to be used in more than 2 files, it’s better to use the header file approach. Some programmers place all of a programs global variables in a file called globals.cpp, and create a header file named globals.h to be included by other .cpp files that need to use them.
Local variables with the same name as a global variable hide the global variable inside that block. However, the global scope operator (::) can be used to tell the compiler you mean the global version:
1
2
3
4
5
6
7
8
9
int nValue = 5;
 
int main()
{
    int nValue = 7; // hides the global nValue variable
    nValue++; // increments local nValue, not global nValue
    ::nValue--; // decrements global nValue, not local nValue
    return 0;
} // local nValue is destroyed
However, having local variables with the same name as global variables is usually a recipe for trouble, and should be avoided whenever possible. Using Hungarian Notation, it is common to declare global variables with a “g_” prefix. This is an easy way to differentiate global variable from local variables, and avoid variables being hidden due to naming collisions.
New programmers are often tempted to use lots of global variables, because they are easy to work with, especially when many functions are involved. However, this is a very bad idea. In fact, global variables should generally be avoided completely!
Why global variables are evil
Global variables should be avoided for several reasons, but the primary reason is because they increase your program’s complexity immensely. For example, say you were examining a program and you wanted to know what a variable named g_nValue was used for. Because g_nValue is a global, and globals can be used anywhere in the entire program, you’d have to examine every single line of every single file! In a computer program with hundreds of files and millions of lines of code, you can imagine how long this would take!
Second, global variables are dangerous because their values can be changed by any function that is called, and there is no easy way for the programmer to know that this will happen. Consider the following program:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// declare global variable
int g_nMode = 1;
 
void doSomething()
{
    g_nMode = 2;
}
 
int main()
{
    g_nMode = 1;
 
    doSomething();
 
    // Programmer expects g_nMode to be 1
    // But doSomething changed it to 2!
 
    if (g_nMode == 1)
        cout << "No threat detected." << endl;
    else
        cout << "Launching nuclear missiles..." << endl;
 
    return 0;
}
Note that the programmer set g_nMode to 1, and then called doSomething(). Unless the programmer had explicit knowledge that doSomething() was going to change the value of g_nMode, he or she was probably not expecting doSomething() to change the value! Consequently, the rest of main() doesn’t work like the programmer expects (and the world is obliterated).
Global variables make every function call potentially dangerous, and the programmer has no easy way of knowing which ones are dangerous and which ones aren’t! Local variables are much safer because other functions can not affect them directly. Consequently, global variables should not be used unless there is a very good reason!

0 comments:

Blogger Template by Clairvo