6.9 — Why global variables are evil

If you were to ask a veteran programmer for one piece of advice on good programming practices, after some thought, the most likely answer would be, “Avoid global variables!”. And with good reason: global variables are one of the most historically abused concepts in the language. Although they may seem harmless in small academic programs, they are often problematic in larger ones.

New programmers are often tempted to use lots of global variables, because they are easy to work with, especially when many calls to different functions are involved (passing data through function parameters is a pain). However, this is generally a bad idea. Many developers believe non-const global variables should be avoided completely!

But before we go into why, we should make a clarification. When developers tell you that global variables are evil, they’re usually not talking about all global variables. They’re mostly talking about non-const global variables.

Why (non-const) global variables are evil

By far the biggest reason non-const global variables are dangerous is 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:

Note that the programmer set variable g_mode to 1, and then called doSomething(). Unless the programmer had explicit knowledge that doSomething() was going to change the value of g_mode, 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).

In short, global variables make the program’s state unpredictable. Every function call becomes 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.

There are plenty of other good reasons not to use non-const globals.

With global variables, it’s not uncommon to find a piece of code that looks like this:

After debugging, you determine that your program isn’t working correctly because g_mode has value 3, not 4. How do you fix it? Now you need to find all of the places g_mode could possibly be set to 3, and trace through how it got set in the first place. It’s possible this may be in a totally unrelated piece of code!

One of the key reasons to declare local variables as close to where they are used as possible is because doing so minimizes the amount of code you need to look through to understand what the variable does. Global variables are at the opposite end of the spectrum -- because they can be accessed anywhere, you might have to look through the entire program to understand their usage. In small programs, this might not be an issue. In large ones, it will be.

For example, you might find g_mode is referenced 442 times in your program. Unless g_mode is well documented, you’ll potentially have to look through every use of g_mode to understand how it’s being used in different cases, what its valid values are, and what its overall function is.

Global variables also make your program less modular and less flexible. A function that utilizes nothing but its parameters and has no side effects is perfectly modular. Modularity helps both in understanding what a program does, as well as with reusability. Global variables reduce modularity significantly.

In particular, avoid using global variables for important “decision-point” variables (e.g. variables you’d use in a conditional statement, like variable g_mode in the example above). Your program isn’t likely to break if a global variable holding an informational value changes (e.g. like the user’s name). It is much more likely to break if you change a global variable that impacts how your program actually functions.

Best practice

Use local variables instead of global variables whenever possible.

So what are very good reasons to use non-const global variables?

There aren’t many. In most cases, there are other ways to solve the problem that avoids the use of non-const global variables. But in some cases, judicious use of non-const global variables can actually reduce program complexity, and in these rare cases, their use may be better than the alternatives.

A good example is a log file, where you can dump error or debug information. It probably makes sense to define this as a global, because you’re likely to only have one log in a program and it will likely be used everywhere in your program.

For what it’s worth, the std::cout and std::cin objects are implemented as global variables (inside the std namespace).

As a rule of thumb, any use of a global variable should meet at least the following two criteria: There should only ever be one of the thing the variable represents in your program, and its use should be ubiquitous throughout your program.

Many new programmers make the mistake of thinking that something can be implemented as a global because only one is needed right now. For example, you might think that because you’re implementing a single player game, you only need one player. But what happens later when you want to add a multiplayer mode (versus or hotseat)?

Protecting yourself from global destruction

If you do find a good use for a non-const global variable, a few useful bits of advice will minimize the amount of trouble you can get into. This advice isn’t only for non-const global variables, but can help with all global variables.

First, prefix all non-namespaced global variables with “g” or “g_”, or better yet, put them in a namespace (discussed in lesson 6.2 -- User-defined namespaces), to reduce the chance of naming collisions.

For example, instead of:

Do this:

Second, instead of allowing direct access to the global variable, it’s a better practice to “encapsulate” the variable. First, make sure the variable can only be accessed from within the file it’s declared in, eg. by making the variable static or const. Second, provide external global “access functions” to work with the variable. These functions can ensure proper usage is maintained (e.g. do input validation, range checking, etc…). Also, if you ever decide to change the underlying implementation (e.g. move from one database to another), you only have to update the access functions instead of every piece of code that uses the global variable directly.

For example, instead of:

Do this:

A reminder

const variables have internal linkage by default, gravity doesn’t need to be static.

Third, when writing an otherwise standalone function that uses the global variable, don’t use the variable directly in your function body. Pass it in as an argument instead. That way, if your function ever needs to use a different value for some circumstance, you can simply vary the argument. This helps maintain modularity.

Instead of:

Do this:

A joke

What’s the best naming prefix for a global variable?

Answer: //

C++ jokes are the best.

6.10 -- Static local variables
6.8 -- Global constants and inline variables

166 comments to 6.9 — Why global variables are evil

  • zukkus

    I think its funny to use the term "constant variable".  Its just a constant right?  Youre basically saying "Jumbo shrimp".  Global constants are absolutely OK especially with the trick shown previously where they wont be copied into every file that includes them.

    Really its just global variables are bad, global constants are good.

    Coming from Java I have to read this stuff 10 times, static and extern and global vs local are all different

    Java does:
    public final static double PI = 3.1415;

    extern static const float PI(3.1415);


  • Brandon Stone

    Maybe I'm too literal, but I don't get the joke. Would someone please explain it.

    • Alex

      // is the start of a comment in C++ -- starting your variable with this prefix would turn your global variable into a comment, rendering it harmless. :)

  • alex bro i have a question , what do you mean by saying that " In the above example, you might find g_mode is referenced 442 times. " ??......

    and one more thing can you please add something like 'notify me by email(whenever someone posts a new comment)' in comment box because one has to check again and again that he has a reply or adding above stuff we can simply get a notification..Please consider adding it.

    • Alex

      I've updated the wording to try and be a little more clearer. It's not uncommon to have hundreds of references to a global variable in a given program, and if you find your global variable has the wrong value, you may have to check hundreds of different places to try to identify which one is at fault. It sucks.

      I'm looking into an email notifier function.

  • Elpidius

    Hey Alex, I just thought I'd mention that I've found three typos:
    "Although they may seem harmless in a small academic programs..."; should say "in small academic programs"

    Here's the second one:
    "... to reduce the chance of naming collisions and raise aware that a variable is global."
    It should say "raise awareness".

    The last one is a comment in your last example:
    "// pass in getGravity() for parameter gravity() if you want to use the global gravity", should just say "gravity" -- without the parenthesis after it.

    Btw, I love the humor mentioned in:
    cout << "Launching nuclear missile...", and "the rest of main() doesn’t work like the programmer expects (and the world is obliterated)". That one cracked me up!

    Also I like the C++ joke mentioned at the end. :)

  • Deep

    Hi Alex,

    In the second point of protecting yourself from global destruction, beside the get_gravity function you commented this line
    //this function can be exported to other files to access the global outside of this file

    How can the global be accessed in other files, the g_gravity is static ?

    This gives undefined reference to g_gravity as expected since g_gravity can't be accessed on any other file as it is static, on commenting the extern line, it gives not declared in scope error.

    So coming back to your commented line in the function how can this function be exported to other files to access the global outside of this file ?

    Another doubt can you explain the difference between non constant global variable -> initialized vs non-initialized?

    • Alex

      I think you've mistaken the intent of the example. You correctly note that because g_gravity is static, it can't be exported. But in this case, that's by design. It's the getGravity() function that we could export, making it available to be called from other files. This doesn't impact g_gravity in any way. e.g.



      > Another doubt can you explain the difference between non constant global variable -> initialized vs non-initialized?

      Non-const globals can be initialized when defined, or not. What are you confused about?

      • Shiva

        Hi Alex,

        In the last chapter you said "Function forward declarations don’t need the extern keyword.". So in the above code (main.cpp) isn't the use of the extern keyword redundant? I just tried without it, and it worked fine. Still I'm asking this to make sure that I've got the concept right. Also, just to satisfy the compiler, shouldn't int main() return a value? Here too, but surprisingly, my compiler didn't complain about the absence of the return statement. Why?

        The last two chapters about the 'global evil' have been real tricky, so I've decided to use global variables only if my life depended on it. Far better than remembering all these stuff.

        And that joke was brilliant! I never expected a joke on something like C++, do add some more in the upcoming chapters. :D

        • Alex

          Yes, you are correct that the extern keyword was redundant. I've edited the previous comment and removed it (as well as fixed the inconsistent function naming).

          Good programming jokes are hard to come by. This thread should be worth at least a chuckle.

          • Shiva

            Okay, thanks for the reply, but you didn't answer my second question: why does it compile without a return statement at the end of main() ?

            Thanks for the link to the Stack Overflow thread, made my day! :)

            • Alex

              Oops. Some compilers (e.g. Visual Studio) will assume you meant return 0 if you omit the return statement at the end of main. This is non-standard behavior and shouldn't be relied upon.

            • Shiva

              Okay. Meanwhile I happened to stumble upon this article ( which lists a few differences b/w C and C++. The author (whose name is Alex too) says:

              "In C++, you are free to leave off the statement 'return 0;' at the end of main; it will be provided automatically, but in C, you must manually add it."

              He seems to consider this a standard, contrary to your answer. But I think you are correct, omitting the return statement does feel pretty non-standard. I'm gonna stick with your suggestion and put 'return 0;' at the end of every program I write.

              • Alex

                It appears that I have been incorrect. The C++ standard says:

                "A return statement in main has the effect of leaving the main function (destroying any objects with automatic storage duration) and calling std::exit with the return value as the argument. If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;"

                I'll update the tutorial articles accordingly.

            • Shiva

              Good thing, Alex! Glad that I could contribute something to the improvement of this awesome site. :)

              I'm gonna put the return statement anyway, feels more comfortable with it than without.

  • Chris

    Hi Alex,
    previously, sorry for my bad English and if I bother you with all question I ask.

    1. I don't understand with "So what are very good reasons to use non-const global variables?" section, I confuse with the example because it seem we can use const global variable, can you make it more clear please? or add more simple example with the code please?

    2. I'm confuse too with second advise in "Protecting yourself from global destruction" section. what is the advantage of use function which return the global variable? I test it, and I got the function cannot be assigned. is that the advantage of this function? so value of the function never be changed?

    3. then the last thing I don't understand is this quote "These functions can ensure proper usage is maintained (e.g. do input validation, range checking, etc…). Also, if you ever decide to change the underlying implementation (e.g. move from one database to another), you only have to update the access functions instead of every piece of code that uses the global variable directly.". can you make it more clear or add more example?

    I'm so mad and confused with this chapter haha..
    thank you.

    • Alex

      1) I can't really provide any good examples at this point because they all rely on more advanced concepts. For now, assume global variables are bad, and when you encounter a situation that you can't figure out how to efficiently deal with without using a global variable, you'll have discovered one of the rare use cases yourself.

      2&3) The advantage of using an encapsulating function is manyfold: First, the function can do any kind of input checking. For example, let's say our global variable is storing the user's name. If direct access to the global variable was provided, any function in the program could set the name to "" (which clearly isn't a valid name). However, if we had a function named setName(), this function could ensure the user had entered a valid name before changing the value of the global variable. Second, let's say we implemented our name global variable as an array of characters. Later on, we want to change to std::string. We can do that, and we just need to modify the setName() function to work properly. Third, if our program isn't working properly, it's much easier to breakpoint the setName() function than it is to try and figure out where everyone who is accessing the global variable directly is.

      For now, it's not too important to understand this in detail. We'll cover encapsulation again in chapter 8 when we talk about object-oriented programming.

  • Unspecified User

    That C++ joke at the end made my day, keep up the good work Alex.

  • Hridayesh

    ok. but once again good work Alex. Thanks

  • Hridayesh

    Hey Alex, these are very nice tutorials. I want to ask you for  a little help. Can you suggest me some good book  or some other source for c++ which has lots of questions in it(I dont care for answers) which i can use as my practice book with your tutorials.

  • rtz

    Hi Alex,
    Can u put some code as an example for the last section "protecting yourself from global destruction" for some better understanding.

  • Kenneth Florek

    Unfortunately I must have learned this seemingly sensible no-globals rule early, probably from reading one of those structured-programming books. When I stepped through the C++ programs in a debugger that would show the  assembly language, I learned that every time a function was called more instructions were executed doing the setup and cleanup than what the functions did. So programs were spending more time with useless rigmarole protocol than doing anything material.It is a sobering experience to watch routines step through 10 levels of calls just to accomplish setting one word in memory. Putting variables in global space, with judicious naming, worked miracles to cut down on the crap. Basically, if you organize yourself, you can do better than what local variables do to contain the effects of sloppy disorganization. Of course if you are a professional programmer, you cannot afford to care if the program ends up 20 times the size of what it might be, and runs at a tenth or a hundredth of the speed it might, because structure is more important than anything.

  • Sosolol

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

    Well that escalated quickly...

  • Maciej

    One reason for globals: access to them is faster than making a copy of variable on the frame stack. In the embedded world it plays a role.

  • techsavvy....aye

    I had problem with understanding the prior and this chapter. I am totally confused please help.
    What else can I do to understand this better.

  • Todd


    "Although they may seem harmless in a small academic programs" (remove 'a' if you want to use the plural 'programs')

    "what it’s (its) valid values are, and what it’s (its) overall function is" ("it's" is only used for "it is". Oddly enough, the possessive form is just "its")

    "(e.g. do input validation, range checking, etc..)." (remove one of the two periods directly after 'etc')

    Also, great timing for some humor! Last lesson was fairly confusing, so the comic relief is appreciated!

  • Yitzi

    For a lot of the good uses of global variables, they need to be read from all over the program, but written to by only one or two functions.&nbsp;&nbsp;While access functions are one way to enforce this (particularly if only the &quot;read&quot; access functions are made external, and the few functions that need to be able to write to the variable are put in the same file), it seems to me that a more performant approach (though one that loses the ability to include range checking and implementation changeability) would be to use an extern const reference.  So it might be:

    Then only the file in which this is contained can change the variable (thereby ensuring that it can't be changed unexpectedly), but any file that declares globalVarAccess can read it, and do so as easily as if it were being accessed directly.

    • Yitzi

      Correction to the above code: That second line would have to be "extern const int".  Fortunately, that would be caught by the compiler when you try to use it in another file...

  • Eric

    Hey!  First time commenting, really enjoying this course.  Quick question, in regard to game development mainly (though the concept could applied to anything really):

    Say for a game, I wanted to have a variable represent something that has tochange throughout the game, but still be accessible in multiple scenarios, like the amount of an item in your inventory.  I might have many variables to do something like that (or possibly an array) it bad practice to use a global variable for something like that?  And is there a better, more efficient way to store information like that?  I'm sure there is, just curious as to what you'd recommend.  I've only worked with Javascript before and used copious amounts of global variables...might be hard to kick the habit!

    • Alex

      Good question, and one that's a little hard to answer right now since we haven't covered the primary concept I'd use to solve for this (classes). But I'll answer anyway.

      An inventory is a discrete set of items, consisting of a item type and a quantity (and maybe a maximum size). An inventory also needs functions to manage the inventory (add an item, consume an item, check if an item exists, etc...). I'd definitely create an Inventory class to encapsulate the inventory details and management.

      But what does an inventory mean by itself? Typically an inventory is owned by someone. Most likely this is the player (but I suppose it could be a monster, or a chest). For now, we'll assume it's the player. The player also has other attributes worth keeping track of, like name, and possibly level, class, health, etc... I'd create a Player class to manage the player attributes. The Player class would also contain an instance of the Inventory class.

      Because there's only one Player, and it really does need to be accessed everywhere, I'd consider making Player global. At least in this case, you only have one global object to manage instead of lots of separate but related global variables, and they're all encapsulated to minimize misuse.

  • 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.

  • dice3000

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

  • Webworks44

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

    "oh shit... my bad"

  • 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?

    • Alex

      If you have only one player, you could consider making all of the player-specific information global. But then what happens when you want to add a multiplayer mode?

      For that reason, I'd probably pass it around.

  • jon Affleck

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

    • Alex

      They are much less dangerous/evil if declared const, to the point where their use is generally acceptable. I've updated the lesson to indicate this.

      Do note that global const variables still pollute the global namespace and are susceptible to naming collisions. Putting them in a namespace can help resolve this.

  • 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.

  • "launching nuclear missiles"was bit scary...! but awesome tutorials ...long live alex..!!

  • 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.

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

      (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.)

  • 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.

  • Alfreda

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

    Now to code my new game: "Pacman XTreme"

    Lol just joking.

  • 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 ;)

  • 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

  • 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).

Leave a Comment

Put all code inside code tags: [code]your code here[/code]