Navigation



4.2 — 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:

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:

// declaration of g_nValue
int g_nValue = 5;

main.cpp:

// 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:

// declaration of g_nValue
int g_nValue = 5;

global.h:

#ifndef GLOBAL_H // header guards
#define GLOBAL_H

// extern tells the compiler this variable is declared elsewhere
extern int g_nValue;

#endif

main.cpp:

#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:

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:

// 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!

4.3 — File scope and the static keyword
Index
4.1 — Blocks (compound statements) and local variables

53 comments to 4.2 — Global variables

  • Vivek Singh

    Thanks that was great!

    I was facing problem with global variable declaration and using it into mutiple files.

    The problem is fixed.

    • papagym177

      The comments in the last program in Sect 4.2 has me confused again. Doesn’t g_nMode get changed back to one (1) in function Main by the next statement- {int g_nMode = 1;… THEREFORE: global it’s 1, dosomething it’s 2, then in main it’s 1 again??? Is one of the declarations hidden again?
      Sorry if I’m so picky ..Thank You.

      Alex:
      The use of the horizontal scroll bar in the tutorials should be deleted. They are annoying and they hide some closing braces.

      • CodeAvenger

        The Function doSomething is called within main. So first the variable g_nMode is equal to 1, because of the global variable with that name. Then it is equal to 1, because when we go into main, there is a local variable, with the same name that is equal to 1. Then the doSomething Function is called and g_nMode is equal to 2. We then go to the if statement that prints out “Launching nuclear missles…”.

  • Sorin

    How do I know if I have a really good reason? Can you give us an example from your experience where you decided you should use a global variable, please?

    • I honestly can’t think of the last time I used a global variable.

      Typically, people use global variables for one of three reasons:
      1) Because they don’t understand C++ variable passing mechanics, or they’re being lazy.
      2) To hold data that needs to be used by the entire program (eg. configuration settings).
      3) To pass data between code that doesn’t have a caller/callee relationship (eg. multi-threaded programs)

      Obviously #1 isn’t a good reason at all. Once you get into C++ classes, there are better ways to do #2 (eg. static classes). That pretty much leaves #3, and maybe a few other cases I’m not aware of.

      Basically, the only time you should use a global variable is if there is no practical way to do what you want using local variables and variable passing mechanics. In my opinion, use of globals should always be a last resort — so in a way, it’s a “you’ll know it when you run into it” situation, as there simply won’t be any other reasonable way to proceed.

      • Jamie

        I use only one global variable in my 1100 line program (simulating disease spread in a population), which is a random number generator from the GNU scientific library. Different functions need to be able to use a generator, and I don’t want to create a new one each time for two reasons:

        a) The generator needs to be seeded from the system time. If it was local to a function, then I’d risk it being seeded by the same value each time. I need the independence throughout my program. I suppose I could declare it static, but why have 7 different RNG generators, when I would be better with just 1?
        b) It’s a random number generator. I expect it to change in between function calls, and don’t need or want consistency.

        For these reasons, it has to be declared global.

        Meanwhile, I have a whole pile of variables which will not change throughout the entire program, e.g. n (the size of the lattice of sites), or the birth/death/migration/infection rates, which are constants I set when I start the program. They’re currently all local variables, but I’ve considered making them global variables as it would make my program easier to understand, as in your reason (2).

  • Stuart

    “Launching nuclear missiles”, LOL. Evil globals; don’t trust ‘em.

    Anyway, I just wanted to say that these tutorials are really good. Thanks. ;D

  • [...] 2007 Prev/Next Posts « 3.8 — Bitwise operators | Home | 4.2 — Global variables » Monday, June 18th, 2007 at 10:06 [...]

  • Travis

    This really cleared up what I wanted to know about global variables.

    I used them in a code for my C++ class, and was told never to use them by my professor.
    I asked him why, and his explanation made it seem (to me!) that they are a good option as far as the flexibility of the program goes.

    No that I know I could accidentally blow up the world, I will avoid them ;)

  • noob1337

    Alex, you are my C++ Jesus. Thank you for spreading the almighty commandments of programming, I worship you for that.

    Actually I had a question but I just figured it out :) Maybe I’ll have one for you later..

  • Alfreda

    Is there really a function that launches nuclear missiles from the computer?

    Now to code my new game: “Pacman XTreme”

    Lol just joking.

  • Elef8eroskopefths

    Thanks 4 all info, but may I ask sth??
    am writin’ a prog the last 3 days and when I initialize a funktion I need some variables (a lot, to be honest :P), which I need in the main() function as well, but the user is the one who decides how many variables there will be every time he uses (‘will use’, when I finish it) the prog. So I cannot declare a function 4 example: ‘func(x;y;z)’ because I cannot know how many the variables will be, so I cannot see a way 2 pass data between functions without global variables….

    Is there sth I don’t know, which I can use at such an example, in order not to use globals???? If yes, I NeEd It

  • Ian

    Well, what happens if I have two different files containing the same variable name, where one of them was intended to be global and the other local. How does the compiler know which variable I am referring to, when I write ‘extern int identifier’ above my int main() block. I guess Im asking this question coz Im used to MatLab7.0 , where i had to prefix “global” to a variable declaration, to denote it was global. This was stored in the workspace during runtime and accessed through there.

    • Generally a local variable will take precedence over a global. eg.

      int nX = 5;
      
      int main()
      {
          {
              int nX = 6;
              nX = 7; // sets local nX, not global nX
              cout << nX; // prints 7
          } // local nX goes out of scope here
      
          cout << nX; // prints 5
      }
      
  • Faykarta

    I do agree with the most part of what you are saying, as long as you are working entirely in C++.

    I think there is still a great use for file scope global variables in C and there are some definite bonuses to using C and C++ combined.

    For example… most cases where you might create a singleton would require that one instance is created for the entirety of the program. If this is the case why not just create C file which contains the desired functions and variables. You can use static as a file scope controller, therefore eliminating many of the frowned upon side features to a singleton implementation. If it is a requirement that the singleton is created and destroyed multiple times throughout the program then C++ is probably a better idea considering the allocation of global/static data happens at program start up.

    The fact is that the main problem we are trying to avoid is breaking encapsulation, as the overhead from C++ is in polymorphism/inheritance. An additional overhead is invoked with passing arguments through functions, and there is a greater overhead (and pain in the ass) setting up dependencies for class instances.

    Its all about encapsulation and im still playing with ideas but please let me know what you think.

    • Dan Dickey

      Global variables are Evil without a doubt. With a capital E!

      static file scoped variables are still global in a sense.
      Unless you have those variables wrapped by a mutex of
      some sort, your code is non-threadable.
      Please try to write thread safe code.

      Global variables are Evil. Do *not* ever use them.

  • Whiskeydash

    Fully mindful of the global warning (and their emissions),
    would “extern” also be used in the case of using a ‘global function‘ if one was er declared (or is it defined..) externally?

  • MusicDave

    I do not understand why main() outputs “Launching nuclear missiles…” to the console.
    Isn’t g_nmode = 2; only local to void doSomething(), and destroyed at the end of this function.
    Also, the global scope operator (::) is not used, so gnMode = 2; is not executed globally, right?
    Thank you.

    // 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;
    }
    
    • chaos

      In the code above, every time g_nMode is called, it is calling the global g_nMode. There isn’t a local g_nMode in the program, because it is never declared locally. However, by slightly editing doSomething(), the expected “No threat detected.” will be the output:

      void doSomething()
      {
          int g_nMode; // now there is a local g_nMode
          g_nMode = 2; // the local g_nMode == 2
      } // the local g_nMode terminates, the global g_nMode == 1 still
      

      (Since the local g_nMode wasn’t global, the g prefix should have been dropped, but I kept it in an attempt to stay close to the code that you had in question. I hope that didn’t confuse you more.)

  • N.Kumaresh

    Thanks for this free, and hence great site.

  • Sam

    In C, I use globals when I need a pointer to the start (and/or end) of a linked list, which is referenced and modified by many functions. Is this wrong?

    In C++, what in essence should I be doing instead to keep track of something like this – the initial address of a linked list- throughout an entire program? I don’t want to pass it around. Am I lazy?

    Thanks for these tutorials – I took out several books from the library to get some answers on use of header files, globals and extern in C++ and none were as helpful as this.

  • Kavya

    Can you tell me wht will happen if below is the case ??

    int gvalue = 5 ;
    main()
    {
    int gvalue = gvalue ;
    print (“%d”,gvalue);
    }

  • Alex B.

    Hi! I’m using Dev-C++, and I’m new to C++

    I copied and pasted the code(s) with the extern variable header.
    I got a compiling error that says that it cannot link them:

    [Link error] undefined refrence ‘to g_nValue’
    [Link error] undefined refrence ‘to g_nValue’
    Id returned 1 exit status

    What’s going on… Please help :(

  • Steve Pedro

    Why is it declared as “g_nValue”, but initialized as “g nValue”?

  • ArnR

    Is there any difference between declaring global variable in C & C++?
    If yes then please explain with an example.

    Thanks for this nice tutorial guide.. :)

  • “launching nuclear missiles”was bit scary…! but awesome tutorials …long live alex..!!

  • Anuradha

    i am using a global variable ‘int bsize’ in multiple file using header file system..i am getting the following error…

    1>keyboard.obj : error LNK2001: unresolved external symbol "int bsize" (?bsize@@3HA)
    1>numpad.obj : error LNK2001: unresolved external symbol "int bsize" (?bsize@@3HA)
    1>debug\part1.exe : fatal error LNK1120: 1 unresolved externals
    

    I have declared it in the file called test1.cpp as

     //test1.cpp//
    
    #include <QtGui>
    #include "test1.h"
    
    QSize Button::sizeHint() const
     {
         QSize size = QPushButton::sizeHint();
    
    	 int bsize = 10;
             size.rheight() -= bsize;
             size.rwidth() = qMin(size.width(), size.height());
    	 return size;
     }
    

    included it with extern keyword in the file test1.h as

    
    //test1.h//
    
    #ifndef BUTTON_H
    #define BUTTON_H
    
    #include <QPushButton>
    #include<QSizePolicy>
    #include<QLineEdit>
    extern int bsize;
    
     class Button : public QPushButton
     {
         Q_OBJECT
    
     public:
         Button(const QString &text, QWidget *parent = 0);
         QSize sizeHint() const;
    	// QFont *font1;
       //int bsize ;
     };
    
     #endif
    

    and then accessed it in two files keyboard.cpp and numpad.cpp as a part of formula

    //keyboard.cpp//
    
    #include "test1.h"
    #include "keyboard.h"
    #include "numpad.h"
    
    Button *keyboard::createButton(const QString &text, const char *member)
     {
    
         Button *button = new Button(text);
         connect(button, SIGNAL(clicked()), this, member);
    	 QFont font1;
         font1.setPointSize(10-(0.1*bsize));
    	// font1.setPointSize(8);
         button->setFont(font1);
    	 return button;
     }
    

    please reply..why is that error? how should i resolve it?

  • [...] 4.2 Global variables (and why they are evil) [...]

  • Tom

    Why global variables are evil ….

    One advantage using global variables is that the same variable doesn’t mean twenty different things in twenty different places. It can get confusing in scientific programming when “energy” means different things in different places.

  • jon Affleck

    I don’t think global variables are dangerous/evil if they are declared ‘const’, since the value cannot be changed.

  • qaz

    @Anuradha: “int bsize” was declared locally in the function sizeHint() in test1.cpp. It doesn’t exist outside that function. Declare it globally in test1.cpp outside any functions.

  • Anthony

    What if I have a global variable, that gets edited in one function, but I need to check it in another function?

  • [...] You're probably using C or C++… … and you probably need to declare "PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP" as a global, "extern" variable in a .h header file. For example: http://www.learncpp.com/cpp-tutorial…bal-variables/ [...]

  • [...] to functions than making them global. You can read some reason why global variables are evil here (scroll down a [...]

  • astronaut13

    Okay. So, a very good reason for a global variable might be in a game – a player’s name and inventory status, etc. Right?

  • hpoonis

    I have to ask…

    Why would you need to create a file (say) globals.cpp AND ALSO globals.h to call the .cpp? Why not just call the file globals.h instead and use that?

    It just seems pointless having two files do the same thing as one.

  • ranjbar

    hi

    #include
    int main()
    {
    using namespace std;
    cout <> nValue;

    if (nValue > 3)

    {
    cout << "A"<<endl;

    cout << "enter a number"<> x;
    }

    }

    suppose out of the block of if i need value of x. what can i do for getting value of x out of the block?

  • anoushe

    Hi,

    I’m trying to solve a matrix equation outside of my main function i.e. I form the matrices A and b in my main function then pass them onto a solver.cpp file which then solves them and gets me the x. I now want to use that x (which is an array defined as double *x=new double [m] ) in my main function. Can someone please help with this? I’ve tried several ways but keep getting errors.
    Thanks a lot!

  • [...] needn’t go too deep into this here, for that we have this great link, but the main take-away is extern tells the compiler this value is defined elsewhere, and so long [...]

  • Webworks44

    if (g_nMode == 1)
    cout << "No threat detected." << endl;
    else
    cout << "Launching nuclear missiles…" << endl;

    "oh shit… my bad"

  • codeez

    It should be noted if your global variables are const and they are to be used externally, their original definitions also need the extern keyword. E.g.:

    // file1.cpp

    // illegal:
    const int x = 33;
    // correct:
    extern const int x = 33;

    // main.cpp
    extern const int x; // forward decleration

    Of course you can actually declare global consts without extern, but if they need external access use extern for both sides!

  • dice3000

    cout << "Launching nuclear missiles…" << endl;
    haha :)

  • [...] that ‘global’ variables are defined outside of a block and have program scope (source: http://www.learncpp.com/cpp-tutorial/42-global-variables/). But the [...]

  • joel.giedt

    I will give a concrete example of when global variables are necessary. This is not to imply that they should not be kept to a minimum — that is certainly true.

    Suppose you are a lattice gauge theorist writing a library intended to solve for quark propagators on GPUs (example, QUDA). It is going to be used by hundreds of people who are integrating it with other codes that they are already using. You want to present users of your library with as simple an interface as possible. That would just be a small set of functions to call, with no fancy abstract types, and perhaps a structure or two to contain parameters. The basic user will be solving a linear algebra problem, MX=B, where M is a large sparse matrix, B is a given “source” vector, and X will be the solution vector. For practical reasons this is done in two steps:

    void load_gauge(void *gauge_array, Params *par);
    void solve(void *solution, void *source);

    load_gauge is done once, but solve is typically done many times with different sources. void pointers are used because different precisions of floating point number are in use, depending on a setting in par. That is for performance reasons. The array gauge_array is loaded to the GPU and a pointer (not gauge_array) to that memory on the GPU must be passed somehow to solve() so that its own functions that it calls to carry out the operation on the GPU can use this array for defining the matrix M. To keep the interface simple, and to hide all of these implementation details from users, the pointer to the GPU memory is passed between the functions using a global variable, say gpu_gauge_array. Note that it is not even in the same memory space as gauge_array.

    The alternative is to force users of the library to adapt to a much more involved interface where they would call functions that are members of classes so that the pointer could be a member variable. This is far from optimal since half the community is actually using C code, not C++ code. By using the simple function interface given above, and a struct for the Params type, it can interface with either type of user. Of course everything in the interface code has to be declared with extern “C”, but that is not a big deal.

    The point of this example is that in the professional setting you may not be writing code just for yourself, or for one company, but you may be writing for a world-wide community that needs simple, flexible code to link to and use. Having a simple interface will often force some data into global scope.

You must be logged in to post a comment.