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. However, 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 an 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

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

  • Danny

    I’m no C++ pro, but from learning from your website, isn’t this a mistake?

    "Note that if you want to define an uninitialized non-const global variable, do not use the extern keyword…"

    Shouldn’t it be "…want to *declare* an uninitialized…"?
    Uninitialized mean it hasn’t been defined, only declared. Am I wrong?

    Yes, I am a pedant, but we pedants have our own learning styles too.

    • Alex

      > Uninitialized mean it hasn’t been defined, only declared. Am I wrong?

      You are wrong. :)

      A declaration associates a name and type, but does not instantiate an object.
      A definition actually instantiates the object.

      The top line in the code block above is a definition of an uninitialized variable. Memory will be allocated for x, even though it hasn’t been assigned a value yet.

      • Danny

        Ah, that helps. So is

        both a declaration and a definition? That’s what this* guy says: "The line int x; both declares and defines the variable." If so, that was the source of my confusion.

        *source: http://www.cprogramming.com/declare_vs_define.html

        • Alex

          Yes, “int x” is both a definition and a declaration. All definitions in C++ are declarations, but only some declarations are definitions. Others, such as forward declarations, are pure declarations.

          I discuss exactly this in lesson 1.7 -- forward declarations.

  • Cevher Bilger

    In your last topic, "Global symbolic constants"; you say "If constants.h gets included 20 times, each of these variables is duplicated 20 times". But there is header guard on constants.h. Does not preprocessor handle the situation in this case? Buy the way, this is a great tutorial. Thanks.

    • Alex

      Header guards prevent a header from being included more than once into the same file.

      in a.cpp:

      Header guards do not prevent a header from being included into multiple separate files.

      in a.cpp:

      in b.cpp:

      In this case, iostream will be copied into both a.cpp and b.cpp.

      Now instead of iostream, let’s assume we’re including a header file full of constants definitions.

      In the first example, a.cpp would only get one copy of those constants.
      In the second example, both a.cpp and b.cpp would get a separate copy of those constants.

  • Matheus Ronfim

    Just to make sure, when you stated that "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."
    isn’t it the other way around? non-const variables are internal and const variables are external? because in the example above, you have the non-const as internal and the const as external:

    I was just a little confused, not sure if you did this intentionally or not. Thanks.

    • Alex

      The statement is correct. The examples above are intended to show how the keywords can be used to change the default state.

      To clarify:

      We can use the static and extern keywords to override the defaults

      I’ll clarify the examples above because I can see how this is confusing.

  • 1915

    I’m really new to coding, so I apologize if this is a stupid question, but I’m getting a little confused.

    Looking at constants.cpp and constants.h, it seems like you’re defining two different namespaces with the same name, "Constants." If in the code file you write:

    which namespace will the compiler look into for "pi"? If it looks into the header file and sees the forward declaration for pi, I’m guessing that redirects it to constants.cpp to find pi’s definition… but is there any conflict that occurs because it will encounter two namespaces with the same name along this path?

    • Alex

      Namespaces can be split across multiple files, with all of the content considered part of the same namespace. So the content defined in constants.cpp is considered part of the same namespace as the content in constants.h, even though the definitions are split across multiple files.

      This allows us to separate out the forward declarations from the definitions, while keeping both in the same namespace.

      • 1915

        Ahh, I see; thank you for your help! After I posted that, I was able to read up to the page on namespaces (4.3a) and I thought that might be the case.

        Thank you for this awesome website! Your guide has been extremely useful, and I appreciate all of your hard work!

  • Todd

    Typo.

    "Similarly, in order to use a (an) external global variable"

  • Shivam Tripathi

    hii alex…ur tutorials are just awesome..m really enjoying it..it has helped me a lot so far…:)
    i hv a li’l bit confusion regarding linkage concept…i searched a lot on web about it but that didn’t satisfy me..moreover in context to ur example given above which tells the forward declaration of variable using "extern", i hv a confusion…
    actually i ran the same code "global.cpp" & "main.cpp" and i didn’t use extern keyword ..yet the program was working correctly and was giving the expected and desired output…and i was able to manipulate those variables values without any problem..
    my quest is that how can it be possible…is extern keyword necessary.or we can skip it…plzz help me out..:)

    • Alex

      Yes, you must use extern to use a variable defined in one file in another file. Without it, you’ll define a new variable of the same name.

      Since you removed the extern keyword, what happened is your main.cpp defined new variables named g_x and g_y instead of using the same g_x and g_y that were defined in global.cpp.

  • Shivam Tripathi

    so it means that if i define a new variable of same name which is in another file then the new variable will shadow that variable from another file…correct??
    and if we want to use that same variable by "include" -ing that file…then we hv to use extern keyword in order to make a reference that we r using the same variable frm that another file…am i right??…:)

    but alex one thing is bothering me…in global.cpp i made sm changes…i defined variables as “static int g_x”.and “static int g_y” by giving both of them value 2..and then #include that global.cpp in main.cpp..
    now in main.cpp..i cout g_x & g_y…nd i got the output of 2 2…so if it was static then why it gave output in another file??..it shud be linked to that translation unit only…??

  • cpplx

    im thinking of those endless chains of pointers leading to pointers leading to pointers leading to pointers….
    the last example in the lesson… forward declaration in .h, definition in .cpp… were not the .cpp files included by default in a project? or the example is assuming an external file?

    and talking about the endless chain… how long is too long? and if that was a person going from office to office just to get departed to the next office… that would be outrageous… does the compiler have problem with that? and I assume the compiled executable is not going through that chain, right?

Leave a Comment

  

  

  

fifteen − twelve =

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