Search

6.4 — Introduction to global variables

In lesson 6.3 -- Local variables, we covered that local variables are variables defined inside a function (or function parameters). Local variables have block scope (are only visible within the block they are declared in), and have automatic duration (they are created at the point of definition and destroyed when the block is exited).

In C++, variables can also be declared outside of a function. Such variables are called global variables.

Declaring and naming 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 global variable being defined:

The above example prints:

3
3
5

By convention, many developers prefix global variable identifiers with “g” or “g_” to indicate that they are global.

Best practice

Consider using a “g” or “g_” prefix for global variables to help differentiate them from local variables.

Global variables have file scope and static duration

Global variables have file scope (also informally called global scope or global namespace scope), which means they are visible from the point of declaration until the end of the file in which they are declared. Once declared, a global variable can be used anywhere in the file from that point onward! In the above example, global variable g_x is used in both functions doSomething() and main().

Because they are defined outside of a function, global variables are considered to be part of the global namespace (hence the term “global namespace scope”).

Global variables are created when the program starts, and destroyed when it ends. This is called static duration. Variables with static duration are sometimes called static variables.

Unlike local variables, which are uninitialized by default, static variables are zero-initialized by default.

Global variable initialization

Non-constant global variables can be optionally initialized:

Constant global variables

Just like local variables, global variables can be constant. As with all constants, constant global variables must be initialized.

Related content

We discuss global constants in more detail in lesson 6.9 -- Sharing global constants across multiple files (using inline variables).

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

New programmers are often tempted to use lots of global variables, because they can be used without having to explicitly pass them to every function that needs them. However, use of non-constant global variables should generally be avoided altogether! We’ll discuss why in upcoming lesson 6.8 -- Why (non-const) global variables are evil.

Quick Summary


6.5 -- Variable shadowing (name hiding)
Index
6.3 -- Local variables

273 comments to 6.4 — Introduction to global variables

  • Chris

    Hi Alex,

    at second paragraph you said "Global variables have global scope (also called “global namespace scope” or “file scope”)". it is true global scope also called file scope? i google them, and i found (at many question in stackoverflow) they are different. file scope is just in a file which mean variable/function have that scope cannot used at other file. global scope is in entire program which mean variable/function have that scope can used at other file.

    so the different between internal global variable and external global variable is only the linkage? internal doesn't have linkage, but external does?

    thank you

    • Alex

      In C++, file scope and global scope are the same thing. However, informally, sometimes people use the terms as you suggest (making the definitions a combination of file scope and linkage). I've added a section to this lesson called "File scope vs. global scope" where I try to disambiguate this question further.

  • Milos

    Hi Alex,

    thnaks for tutorial!

    In the first example you should write void doSomething(), or write return statement.

  • Matt

    At the top of the lesson, you wrote:
    "local variables... have automatic duration (they are created when the block is entered and destroyed when the block is exited)."

    According to the previous lesson, local variables are created at the point of definition within a block, not necessarily when the block is entered.

  • Am

    Hi Alex,

    line 11 in summery code should be const keyword or static?

    "const int g_y(1); // defines initialized static variable (internal linkage)"

    Thanks

  • Pedro Peck

    How do I extern a multidimensial array?

  • Jonas

    Hi Alex!

    First of all, thanks for this very concise tutorial - it has really helped me improving my programming skills.

    But now to my question, which might not be as relevant since we're only working with IDEs but I'm still curious:
    How do you compile programs with global variables in separate files (like in your example with global symbolic constants) with a makefile?

    I have been able to successfully compile programs with a makefile when doing this with functions in separate files, but it wouldn't compile with extern const variables.
    Thanks

  • Andy

    ugh, been re-reading some of this for the last ~hour, and still can't figure out why this doesn't make sense to me. You have the note "Note that if you want to define an 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.", but are you not doing exactly that in your earlier example?

    • Alex

      My example is of an initialized non-const variable. The warning was for uninitialized non-const variables.

      Because this area tends to cause so much confusion, I've provided a summary table in lesson 4.3a.

  • Tung Nguyen

    Hi there,

    Thank you for the great website. It helps me a lot with C++. As I read through the section, a question arises.

    Is there any difference between global variable and global variable with the keyword extern before it?

    As I know, global variables have external linkage which it can be used in many files. Why do we need the keyword extern before it?

    Thank you for your time.

    Best,

    Tung Nguyen.

    • Alex

      You don't need to use the extern keyword for non-const global variables, as they're already extern by default. But const global variables are internal by default, so if you want to use them across multiple files you'll need to explicitly use the extern keyword:

  • Professzore

    Hi,

    In this very short line of code:

    unary operator :: has the highest precedence among all operators, so will be evaluated first (we'll use the global value variable), and then decrease it's value by 1 (post-decrement operator), and finally assign it to the global value variable.
    Do I understand it well or not?
    Thanks

    • Alex

      Yes, :: is evaluated first. Then operator-- is evaluated, which decrements value by 1, and evaluates to the former value of value, which is discarded.

      There's no separate assignment step here.

  • Chris

    I have copped your code that uses a header file to declare certain constants and use them in a different file, but the IDE I use fails to build an executable, even after changing "radius" to a literal integer.

    I have had other strange problems with Eclipse's C++ IDE.  Do you know if there are particular problems with this specific IDE?

    Here is the code:

    main4_3.cpp

    helpper.h

    helpper_4_1.cpp

  • J3ANP3T3R

    i got a bit confused. in this section ;

    "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"

    i thought the Header Guards would have prevented that from happening ?

    #ifndef CONSTANTS_H
    #define CONSTANTS_H
    #endif

    • Alex

      I've updated the lesson text slightly to address this: Header guards won't stop this from happening, as they only prevent a header from being included more than once into a single including file, not from being included one time into multiple different code files.

  • Yuval

    Thank you so much Alex for running this great site for so long - I really LOVE it that it is so well updated and explains every little question I might ask myself - I haven't encountered this excellent level of detail anywhere else. The comments section is also very helping, as it answers those very intricate topics that are sometimes still bugging me even after your wonderful lessons :)
    I really suggest adding the comments about header-guards not actually guarding from defining the same variables in different files instead of just declaring them, in the lesson's body itself. Thanks!!!

  • OPENG

    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.

    Doesn't Header Guards work here? Why included 20 times? Doesn't preprocessor work?

    • Alex

      Header guards prevent a header file from being included multiple times in a single file.
      Header guards do not prevent a header file from being included once into multiple different files.

      Therefore, if your header file is included once into 20 different files, you'll end up with 20 different copies of the contents, header guards or not.

  • MechanicNeurons

    NOTE FOR ALEX: contents are quite precious but the website format a little bit tricky. when I want to work half screen the main content shrinks in the middle of the webpage in order to show left and right columns without horizontal scroll. after it shrinks it is very difficult to read especially the example codes in the text. that's why I use adblock. I blocked the left and right columns and now I only see the middle column as wide as chrome window. (if you are bored go to the last sentence). adblock remembers this configuration even after I pass to the next chapter. but adblock also blocks the ads (you don't say). generally I dont use adblock on the websites as long as I believe they do a good job and also if they don't have very very annoying adds. but unfortunately your website has written a new rule to force me to use. everyday I visit this website and study, when I am tired I go to internet explorer and click your adds.
    please rearrange your website so when we use it half screen it will show the main content as wide as possible, so I (maybe we) can disable adblock..

    • Alex

      Okay, I'm running an experiment. When your window is half of your screen or smaller, the right sidebar should collapse. The left one will stay since it contains navigation elements.

  • Pan

    Hey Alex,
    I tried to include the "constants" header file into multiple cpp files:

    But there were no performance issues as you said that these constants will be copied multiple times, the visual studio compiler gave me error messages.(something like that variables have been defined multiple times.)

    Did I make some mistakes?

  • Jim

    Alex,
    This lesson is a bit confusing.  Are you saying the keywords static and extern are used to refer to a functions linkage? That you can't use static int add (int x, int y);, or use a (static const )to do a forward declaration of a function but int add ( int x, int y ); will work?  
    In the note that follows, it looks like you actually did what the note says not to do in the second main.cpp function above this  when you used  extern int g_x;
    Note that if you want to define an 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.  I may be missing something here, can you please help.

    • Alex

      Yes, the lesson is difficult because C++ is confusing in this regard. Static and extern are used to explicitly set the linkage of a function or variable to internal or external respectively.

      You can use static int add(int x, int y) to do a forward declaration, but only if the function add() is declared in the same file (because static functions have internal linkage).

      > Note that if you want to define an 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.

      int g_x; tells the compiler that I'm defining an int variable named g_x, and that variable should be instantiated.
      extern int g_x; tells the compiler that I've defined a int variable named g_x in another file, but want to use it here.

      So if we want an uninitialized non-const global variable, we don't use extern, otherwise we fall into the second case.

  • Muhammad Kamal

    "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." <--- Assumed by the compiler or generally between developers and programmers?

    Proofreading ^__^

    • A variable with internal linkage is called [b]a[/b] internal variable
    • Note that if you want to define [b]a[/b] uninitialized non-const global variable
    • and the other uses will simply [b]reference[/b] (should be 'refer to') the version in constants.cpp.

    Also do I get notified somehow that someone replied to my submission? Or I'll have to keep checking back?

  • Lokesh

    @Chang
    Because the name(identifier) of a namespace should be unique. "Constants" and "constants" are two different identifiers. So, when the compiler sees the forward declaration of 'pi' it compiles fine. But in the linking stage, when the linker looks for a definition of 'pi' in "constants" namespace, it cannot find it because there is no namespace named "constants".

  • Chang

    Hi Alex, I manually typed out the codes for constants.h and constants.cpp in the following way:

    constants.cpp

    constants.h

    it has an error, but i resolved in when i changed the capital "C" in constants.cpp to a small letter "c". Seems like the namespace definitions in both the .cpp and .h files need to be the same. Why is this so?

  • Lokesh

    "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."
    How is a global variable referenced? Is this handled by the linker? If so, is it the same way as a function linking works?

    • Alex

      A global variable is referenced by name, just like any other variable. The linker handles figuring out how to connect references to the global variable with where the global variable was defined. Function linking works the same way (you call a function that lives somewhere, it's up to the linker to connect the function call to the function definition, which may be in a different file).

  • Soul

    Hi, I tried following your instructions here but got some issues. What I have is:

    main.cpp

    Console.h

    functions.cpp

    While the extern keyword is in namespace, I get the error:
    "
    -------------- Build: Debug in 6th Project (compiler: GNU GCC Compiler)---------------

    mingw32-g++.exe -Wall -fexceptions -g -std=c++11  -c "C:\Users\Cybermastah\Documents\CB projects\6th Project\functions.cpp" -o obj\Debug\functions.o
    mingw32-g++.exe -Wall -fexceptions -g -std=c++11  -c "C:\Users\Cybermastah\Documents\CB projects\6th Project\main.cpp" -o obj\Debug\main.o
    mingw32-g++.exe  -o "bin\Debug\6th Project.exe" obj\Debug\functions.o obj\Debug\main.o  
    obj\Debug\main.o:main.cpp:(.rdata+0x8): multiple definition of `Consta::gravity'
    obj\Debug\functions.o:functions.cpp:(.rdata+0x8): first defined here
    collect2.exe: error: ld returned 1 exit status
    Process terminated with status 1 (0 minute(s), 1 second(s))
    0 error(s), 0 warning(s) (0 minute(s), 1 second(s))

    "

    But when I REMOVE the extern keyword it works fine. I tried adding 'using namespace Consta;' to both files and to one file and the problem persisted regardless. I can't get the extern keyword to work properly.

    • Soul

      Never mind, just realized I need to treat the header file as merely the place to stick forward declarations reaching into a cpp file for the number instead. I thought "since it works WITHOUT extern, why would I use extern?" So I went back to the lesson to see why extern is useful and remembered that you mentioned to use the header as a place to stick the namespace as a forward declaration instead, leading to a cpp file where the actual value is located.

      I'd still be grateful for an explanation for why my previous code refuses to compile though :-)

      Even if it makes further repeats of this and bloats the code, I don't see why it wouldn't do so anyway (unless code::blocks specifically doesn't allow it?).

      • Alex

        An initialized constant declared with the extern keyword has external linkage. Since your gravity variable is getting #included in both main.cpp and functions.cpp, both get a copy of the definition for gravity. Since both versions of gravity have external linkage, they collide, and this causes a naming conflict.

        Removing the extern causes them to have internal linkage. main.cpp and functions.cpp still get a copy of gravity, but with internal linkage neither copy of gravity can see the other, so there's no conflict.

  • Ella

    I'm confused about non-const variables and the need for extern.

    It says "By default, non-const variables declared outside of a block are assumed to be external."

    Then later on it says "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."

    Why is extern required if non-const variables are extern by default?

    • Alex

      With functions, a function without a body is assumed to be a forward declaration for a function declared elsewhere.
      With non-const variables, C++ assumes an uninitialized non-const variable is meant to be an uninitialized variable declaration. If you want it to be a forward declaration for the variable, you have to use the extern keyword.

      This sentence seems to cause more confusion than clarity, so I've removed it. :)

  • Peter

    While I didn't try to compile the code myself, I still think there is a mistake in the code:

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

    Then the code:
    constants.cpp:

    constants.h:

    There shouldn't be the "extern" modifier in "constants.cpp", because those variables need to be defined somewhere (that is with no "extern" modifier). Am I right ?
    Also, if you define variables inside of a namespace ("Constants" in the example), can you still say that those variables are global ?

    • Peter

      Sorry for that last question - should have read the chapter about namespaces, before posting any questions - I got it now.
      Nonetheless, the gist of my previous comment remain - there shouldn't be any "extern" keywords in "constants.cpp"

    • Alex

      Remember that const variables have internal linkage by default. The extern in the constants.cpp makes these variables have external linkage.

      This is one of the more confusing parts of C++, in that the extern keyword has two meanings depending on context. It can mean, "I'm declaring a variable here and I want it to have external linkage", or "I've declared a variable elsewhere and want to use it here".

      That's why I provided the chart in the summary. You can see that these variables match this pattern:

      extern const int g_w(1); // defines initialized const global variable (external linkage)

      A global variable in a namespace is still a global variable, it's just inside a namespace as well. :)

  • Sean Kelly

    Hey Alex,

    I was working on a small project of mine when I decided that for the sake of learning I wanted to split my constant variables from one header to another, justly naming the new header, constants.h. I also decided that I wanted to initialize the constants in another .cpp file named constants.cpp and have it #include the prior header file.

    Now when I decided to call the constant variable in my main .cpp file using cout or the like it works fine, HOWEVER, when I decided to use my variable in the creation of a multi-dimensional array it gives me the following error, "Error: expression must have a constant value", funny thing is I am declaring these variables as extern and const and I am including the header file in both my main.cpp and constants.cpp, so I am at a loss.

    • Alex

      C++ is full of little weirdnesses, and it appears you found one.

      When a constant is external, the compiler doesn't know what value it has at compile time (it only knows at link time). Therefore, an extern const can't be used as a compile-time constant (which is required for fixed-size arrays).

      Since your size is presumably an integer, I'd just define the const in the header file directly. If it gets copied into ten or twenty .cpp files, it's no problem, it's just an integer.

  • mrrhq

    Hmm... I never really liked learning about how the code and variable abstraction work this way using static and extern types. It makes C++ more of a confusing language to me. So using extern is like using a "prototype variable", much like prototyping a function, right?

    When you prototype a function, you have to specify the name of the function and its arguments, but you don't prototype a variable, you declare it. So when you use extern, does that mean you declare it in a different scope? Does that mean that a global variable no longer becomes global? I don't understand the point of this...

    I also think "static" has to be the most confusing keyword/statement of them all. I have no real technical information of what it does. Does it just protect the variable from being used by other scopes or outside the function, or does it have more uses? Sorry but, if I ever program in C++, I will never use the static statement, since nobody seems to really give me information on EXACTLY what it does, EXACTLY. It's kinda stupid.

    • mrrhq

      Okay, I'm now trying to read Section 4.3, which talks about the static keyword, but I'm still a little confused about extern. Maybe I'll find a use for it someday.

    • Alex

      Externing a variable is just like prototyping a function (except for variables). A global variable is still global, it's just now also accessible in the scope in which it was externed.

      In the context of a global variable, static causes the variable to have internal linkage, so it can't be extern'd. Static has a different meaning in the context of local variables (it changes their duration). We cover that in lesson 4.3.

  • Samitha

    Thank a lot Alex. Your C++ tutorials taught me C++. This tutorial set is great.

  • Benny

    what are these files you talk about, which headers are included in? aren't files compiled away?

  • omar

    Am glad that i found this site Alex .But am having a bit of a problem right now . It seem like even tho i can understand the topics and the ideas when u give us a quiz to write i always get it wrong and my code is way off to yours . How can i learn to implement your topics into my code and how can i improve . Thank you

    • Alex

      It's okay for your code to be different, as long as you're following good programming principles. My solutions indicate how I'd solve the problem. If you did something differently than me, make sure you understand how my program works, then look at your own program and see how you might have improved it. Then you'll know for next time. It's all about learning along the way, not necessarily doing it perfectly the first time. :)

  • sniper

    • Alex

      I ran this in Visual Studio 2015 and got 12 for the second to last value, and 16 for the final value (which is correct, as you've used a post-increment rather than a pre-increment here).

Leave a Comment

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