Search

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:

5
10
5

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:

5
10
10

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
Index
6.4 -- Introduction to global variables

16 comments to 6.5 — Variable shadowing (name hiding)

  • Math

    Hello,
    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!

    Luke

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