Search

Meta

4.2 — Global variables and linkage

In the last lesson, you learned that variables declared inside a block are called local variables. Local variables have block scope (they are only visible within the block they are declared), and have automatic duration (they are created when the block is entered and destroyed when the block is exited).

Variables declared outside of a block are called global variables. Global variables have static duration, which means they are created when the program starts and are destroyed when it ends. Global variables have global scope (also called “global namespace scope” or “file scope”), which means they are visible until the end of the file in which they are declared.

Defining global variables

By convention, global variables are declared at the top of a file, below the includes, but above any code. Here’s an example of a couple of global variables being defined.

Similar to how variables in an inner block with the same name as a variable in an outer block hides the variable in the outer block, local variables with the same name as a global variable hide the global variable inside the block that the local variable is declared in. However, the global scope operator (::) can be used to tell the compiler you mean the global version instead of the local version.

This code prints:

global value: 4
local value: 8

However, having local variables with the same name as global variables is usually a recipe for trouble, and should be avoided whenever possible. By convention, many developers prefix global variable names with “g_” to indicate that they are global. This both helps identify global variables as well as avoids naming conflicts with local variables.

Internal and external linkage via the static and extern keywords

In addition to scope and duration, variables have a third property: linkage. A variable’s linkage determines whether it can be referenced by other files.

A variable with internal linkage is called a internal variable (or static variable), and it can only be used within the file it is defined in. A variable with external linkage is called an external variable, and it can be used both in the file it is defined in, as well as in other files.

If we want to make a global variable internal (able to be used only within a single file), we can use the static keyword to do so:

Similarly, if we want to make a global variable external (able to be used anywhere in our program), we can use the extern keyword to do so:

By default, non-const variables declared outside of a block are assumed to be external, and const variables declared outside of a block are assumed to be internal.

Variable forward declarations via the extern keyword

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 function forward declaration.

Similarly, in order to use a external global variable that has been declared in another file, you have to use a variable forward declaration. For variables, creating a forward declaration is also done via the extern keyword.

Here is an example of using a variable forward declaration:

global.cpp:

main.cpp:

If the forward declaration is declared outside of a block, it applies for the whole file. If the forward declaration is declared inside a block, it applies within that block only.

If a variable is declared as static, trying to use a forward declaration to access it will not work:

constants.cpp:

main.cpp:

Note that if you want to define a uninitialized non-const global variable, do not use the extern keyword, otherwise C++ will think you’re trying to make a forward declaration for the variable.

Side note on function linkages

Functions have the same linkage property that variables do. Functions always default to external linkage, but can be set to internal linkage via the static keyword:

Function forward declarations don’t need the extern keyword. C++ is able to tell whether you’re defining a function or a function prototype by whether you supply a function body or not.

Non-const variables are a little more complex since they can be defined either initialized and uninitialized, which is why the explicit use of extern is required.

Global symbolic constants

In section 2.9 -- Symbolic constants and the const keyword, we introduced the concept of symbolic constants, and defined them like this:

constants.h:

While this is simple (and fine for smaller programs), every time constants.h gets #included, each of these variables is copied into the including code file. If constants.h gets included 20 times, each of these variables is duplicated 20 times. That’s not too much of a problem here, but if this list of constants were large, and/or included memory-intensive variables, it could lead to code bloat.

We can avoid this problem by turning these constants into const global variables, and making the header file hold only the variable forward declarations:

constants.cpp:

constants.h:

Use in the code file stays the same:

Now the symbolic constants will get instantiated only once (in constants.cpp), instead of once every time constants.h is #included, and the other uses will simply reference the version in constants.cpp.

Because global symbolic constants should be namespaced and are read-only, the use of the g_ prefix is not necessary.

A word of caution about (non-const) global variables

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, use of non-const global variables should generally be avoided altogether! We’ll discuss why in the next section.

Summary

Global variables have global scope, and can be used anywhere in the program. Like functions, you must use a forward declaration (via keyword extern) to use a global variable defined in another file.

By default, non-const global variables have external linkage by default.
By default, const global variables have internal linkage by default. You must use the extern keyword to explicitly make them external if desired.

Use a g_ prefix to help identify your non-const global variables.

Here’s a summary chart of the use of the extern keyword for non-const and const variable use cases:

Quiz
1) What’s the difference between a variable’s scope, duration, and linkage? What kind of scope, duration, and linkage do global variables have?

Quiz Solutions

1) Show Solution

4.2a -- Why global variables are evil
Index
4.1a -- Local variables, scope, and duration

28 comments to 4.2 — Global variables and linkage

  • 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_mode get changed back to one (1) in function Main by the next statement- {int g_mode = 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.

      • CodeAvenger

        The Function doSomething is called within main. So first the variable g_mode 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_mode is equal to 2. We then go to the if statement that prints out “Launching nuclear missiles…”.

        • Alex

          There is no local variable named g_mode. There is only a global variable named g_mode.

          When main sets g_mode to 1, it’s somewhat redundant because g_mode was already set to 1 when it was initialized.

          Then doSomething() is called, which changes the value of g_mode to 2.

          When the if statement executes, (g_mode == 1) evaluates to false, so the else statement case is executed.

          And then the world ends.

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

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

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

    • Alex

      The extern keyword can be used with forward declaration for functions. However, unlike variables (which need the keyword extern to indicate that the declaration is a forward declaration), function forward declarations are assumed to be extern, so use of the extern keyword is optional (and redundant) with function prototypes.

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

    • Delaney

      when you use:

      it uses the local gvalue and returns
      local gvalue = -858993460

      if you wanted it to return 5 use the code:

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

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

  • Anuradha

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

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

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

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

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

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

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

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

    • Alex

      Thanks for the tip. I’ve updated the lesson to include this information.

      Unfortunately, the fact that non-const and const global variables behave differently makes this section a little more complicated than it was before.

  • Jack

    Hey, I am a bit confused about the conversion of the constants.h into external constants to reduce bloating part, I include the constants.h file in the main program but what about constants.cpp, don’t I need to include it also or how do I link it?

  • cpplearner

    When you state:

    "While this is simple (and fine for smaller programs), every time constants.h gets #included, each of these variables is copied into the including code file. If constants.h gets included 20 times, each of these variables is duplicated 20 times. That’s not too much of a problem here, but if this list of constants were large, and/or included memory-intensive variables, it could lead to code bloat."

    From what I remember from the previous lessons you said that using the preprocessor commands like #ifndef #define and #endif, even if you do include the file multiple times they will not be duplicated. What is the difference? Or am I completely missing some point here?

    • Alex

      I see I wasn’t as clear as I could have been. Header guards are meant to prevent the same header file from being included multiple times into the same sound file.

      Header guards do not prevent the header file from being included once into multiple different files.

      In this case with the symbolic constants, it’s the latter case that I’m talking about.

  • Hi, In the example above, it is actually global value of 4 and local value of 8.

    BTW nice work…

    I’m following each word of this tutorial.

    cheers!!!

Leave a Comment

  

  

  

3 × 4 =

Put C++ code inside [code][/code] tags to use the syntax highlighter