6.5 — Variable shadowing (name hiding)

Each block defines its own scope region. So what happens when we have a variable inside a nested block that has the same name as a variable in an outer block? When this happens, the nested variable “hides” the outer variable in areas where they are both in scope. This is called name hiding or shadowing.

Shadowing of local variables

If you run this program, it prints:


In the above program, we first declare a variable named apples in the outer block. This variable is visible within the inner block, which we can see by printing its value (5). Then we declare a different variable (also named apples) in the nested block. From this point to the end of the block, the name apples refers to the nested block apples, not the outer block apples.

Thus, when we assign value 10 to apples, we’re assigning it to the nested block apples. After printing this value (10), nested block apples is destroyed. The existence and value of outer block apples is not affected, and we prove this by printing the value of outer block apples (5).

Note that if the nested block apples had not been defined, the name apples in the nested block would still refer to the outer block apples, so the assignment of value 10 to apples would have applied to the outer block apples:

The above program prints:


When inside the nested block, there’s no way to directly access the shadowed variable from the outer block.

Shadowing of global variables

Similar to how variables in a nested block can shadow variables in an outer block, local variables with the same name as a global variable will shadow the global variable wherever the local variable is in scope:

This code prints:

local variable value: 8
global variable value: 5

However, because global variables are part of the global namespace, we can use the scope operator (::) with no prefix to tell the compiler we mean the global variable instead of the local variable.

This code prints:

local variable value: 8
global variable value: 4

Avoid variable shadowing

Shadowing of local variables should generally be avoided, as it can lead to inadvertent errors where the wrong variable is used or modified. Some compilers will issue a warning when a variable is shadowed.

For the same reason that we recommend avoiding shadowing local variables, we recommend avoiding shadowing global variables as well. This is trivially avoidable if all of your global names use a “g_” prefix.

Best practice

Avoid variable shadowing.

6.6 -- Internal linkage
6.4 -- Introduction to global variables

22 comments to 6.5 — Variable shadowing (name hiding)

  • James C

    Initializing apples{ 0 } when immediately changing it afterward in the first example, may want to change it to apples{}

  • Best practice

    Avoid variable shadowing.

    I love your sense of humour

  • kutlu

    The result of below code is:
    local variable value: 8
    global inside local: 5
    global variable value: 4

    The outcome of below code is:
    local variable value: 8
    global inside local: 4
    global variable value: 4

    Difference lines of code are  


    . You mentioned that problem in CH-5.4 . But I dont understand in that code why they behave different although value variable decreased before  

    • nascardriver

      --prefix returns the new value of the variable.
      postfix-- returns the old value of the variable.
      This isn't a problem, that's what the operators are meant to do.

  • Yousuf

    Beware of the following codes:

    If you are going to suppose that this code snippet is going output: 10, 11, 11; you are wrong. The actual out is as follows:

    My inference is that apple is newly defined inside nested block which has different memory address than the outer block's apple, but this newly defined apple is destroyed at the end of the nested block thus no relationship with the outer block's apple. Indeed nested block apple had no relationship with outer block after it was defined inside nested block. [Please correct me if I am wrong]

    Now look at this code:

    Now this snippet of code works as expected. And this code snippet returns as the following:

    • Bryan

      Your first snippet of code is creating a new variable "apple" (using copy assignment I think) inside the nested block that hides (or shadows) "apple" in the outer block. The second snippet doesn't create a new variable, it assigns a new value (11) to the "apple" already initialized in the outer block.

      This is a good example of what this page of the tutorial is talking about! :)

  • Math

    Where do warnings show up in visual studio?

  • aspiring1

    Hi Alex, Nascardriver,

    I see that the local variable gets destroyed at the end of main() as it was defined here, but also the program ends at the completion of main, so I am assuming global variables also get destroyed at the ned of the last brace. Am I correct?

  • Fensox

    I have to say it from some mountaintop so I'll pick this one as its where I ended up right after the epiphany. I've been coding for 30 years, mostly pascal and java, and have just now finally realized that the ++ in C++ is a play on x++. --Me.

  • Mike

    Hey nascardriver

    Found an inconsistency with the best practices that I wanted to report. In the second source code, "apples" is initialized using direct initialization instead of brace initialization.

  • Luke

    Hello, and thank you very much for all of your hard work in providing this invaluable resource for many folks who wish to learn about programming.

    Is there any specific circumstance that variable shadowing would actually be useful?

    I suppose with quite the complex program, with many different variables and calculations etc., and program control flow also being quite complex, I might be able to think of a case.

    Many thanks!


    • Alex

      Imagine what might happen if you didn't have shadowing -- a variable added to an outer scope could cause inner scopes (that you hadn't touched) to stop compiling. So it's useful in that context in that you don't have to make sure new outer scope additions don't have naming conflicts with inner scope variables.

      • Luke

        Ah yes. I see that this feature is very useful for program construction.

        What about local variable shadowing? Are there any specific fields of computer programming that make use of it? Have you ever run into a circumstance where you found it useful?

  • Sinethemba

    Hi Alex or nascardriver. Can you guys please explain to me why the output is 6 in the below code?

    • nascardriver

      The inner `j` shadows the outer `j`. Your code is equivalent to

Leave a Comment

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