# Variable shadowing

> Mediated Wiki article. Canonical URL: https://mediated.wiki/source/Variable_shadowing
> Markdown URL: https://mediated.wiki/source/Variable_shadowing.md
> Source: https://en.wikipedia.org/wiki/Variable_shadowing
> Source revision: 1301273473
> License: Creative Commons Attribution-ShareAlike 4.0 International (https://creativecommons.org/licenses/by-sa/4.0/)

{{Short description|Variable masking one with the same name}}

In [computer programming](/source/computer_programming), '''variable shadowing''' occurs when a variable declared within a certain [scope](/source/Scope_(computer_science)) (decision block, method, or [inner class](/source/inner_class)) has the same name as a variable declared in an outer scope. At the level of [identifiers](/source/Identifier_(computer_languages)) (names, rather than variables), this is known as [name masking](/source/name_masking). This outer variable is said to be shadowed by the inner variable, while the inner identifier is said to ''mask'' the outer identifier. This can lead to confusion, as it may be unclear which variable subsequent uses of the shadowed variable name refer to, which depends on the [name resolution](/source/Name_resolution_(programming_languages)) rules of the language.

One of the first languages to introduce variable shadowing was [ALGOL](/source/ALGOL), which first introduced blocks to establish scopes. It was also permitted by many of the derivative programming languages including [C](/source/C_(programming_language)), [C++](/source/C%2B%2B) and [Java](/source/Java_(programming_language)).  

The [C#](/source/C_Sharp_(programming_language)) language breaks this tradition, allowing variable shadowing between an inner and an outer class, and between a method and its containing class, but not between an if-block and its containing method, or between case statements in a [switch](/source/Switch_statement) block.

Some languages allow variable shadowing in more cases than others. For example [Kotlin](/source/Kotlin_(programming_language)) allows an inner variable in a function to shadow a passed argument and a variable in an inner block to shadow another in an outer block, while [Java](/source/Java_(programming_language)) does not allow these (see the example below). Both languages allow a passed argument to a function/Method to shadow a Class Field.<ref>{{Cite web |url=https://allegro.tech/2018/05/From-Java-to-Kotlin-and-Back-Again.html |title=From Java to Kotlin and Back Again |access-date=2021-10-04 |archive-date=2020-11-28 |archive-url=https://web.archive.org/web/20201128024109/https://allegro.tech/2018/05/From-Java-to-Kotlin-and-Back-Again.html |url-status=live }}</ref>

Some languages disallow variable shadowing completely such as [CoffeeScript](/source/CoffeeScript)<ref>{{Cite web |url=https://github.com/jashkenas/coffeescript/issues/2697 |title=Please introduce explicit shadowing · Issue #2697 · jashkenas/Coffeescript |website=[GitHub](/source/GitHub) |access-date=2021-10-04 |archive-date=2021-10-04 |archive-url=https://web.archive.org/web/20211004092726/https://github.com/jashkenas/coffeescript/issues/2697 |url-status=live }}</ref> and [V (Vlang)](/source/V_(programming_language)).<ref>{{Cite web |url=https://github.com/vlang/v/blob/master/doc/docs.md#warnings-and-declaration-errors |title=Vlang documentation- "Unlike most languages, variable shadowing is not allowed"|website=[GitHub](/source/GitHub)|access-date=2024-06-27}}</ref>

==Example==
===Lua===
The following [Lua](/source/Lua_(programming_language)) code provides an example of variable shadowing, in multiple blocks.
<syntaxhighlight lang="lua">
v = 1 -- a global variable

do
  local v = v + 1 -- a new local that shadows global v
  print(v) -- prints 2

  do
    local v = v * 2 -- another local that shadows outer local v
    print(v) -- prints 4
  end

  print(v) -- prints 2
end

print(v) -- prints 1
</syntaxhighlight>

===Python===
The following [Python](/source/Python_(programming_language)) code provides another example of variable shadowing:
<syntaxhighlight lang="python">
x = 0

def outer():
    x = 1

    def inner():
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# prints
# inner: 2
# outer: 1
# global: 0
</syntaxhighlight>

As there is no variable declaration but only variable assignment in Python, the keyword <code>nonlocal</code> introduced in Python 3 is used to avoid variable shadowing and assign to non-local variables:
<syntaxhighlight lang="python">
x = 0

def outer():
    x = 1

    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# prints
# inner: 2
# outer: 2
# global: 0
</syntaxhighlight>

The keyword <code>global</code> is used to avoid variable shadowing and assign to global variables:
<syntaxhighlight lang="python">
x = 0

def outer():
    x = 1

    def inner():
        global x
        x = 2
        print("inner:", x)

    inner()
    print("outer:", x)

outer()
print("global:", x)

# prints
# inner: 2
# outer: 1
# global: 2
</syntaxhighlight>

===Rust===

<syntaxhighlight lang="rust">
fn main() {
    let x = 0;
    
    {
        // Shadow
        let x = 1;
        println!("Inner x: {}", x); // prints 1
    }
    
    println!("Outer x: {}", x); // prints 0
    
    let x = "Rust";
    println!("Outer x: {}", x);  // prints 'Rust'
}

//# Inner x: 1
//# Outer x: 0
//# Outer x: Rust

</syntaxhighlight>

=== C++ ===
<syntaxhighlight lang="c++">

#include <iostream>

int main()
{
  int x = 42;
  int sum = 0;

  for (int i = 0; i < 10; i++) {
    int x = i;
    std::cout << "x: " << x << '\n'; // prints values of i from 0 to 9
    sum += x;
  }

  std::cout << "sum: " << sum << '\n'; // prints 45
  std::cout << "x:   " << x   << '\n'; // prints 42

  return 0;
}
</syntaxhighlight>

=== Java ===
<syntaxhighlight lang="java">
public class Shadow {
    private int myIntVar = 0;

    public void shadowTheVar() {
        // Since it has the same name as above object instance field, it shadows above 
        // field inside this method.
        int myIntVar = 5;

        // If we simply refer to 'myIntVar' the one of this method is found 
        // (shadowing a second one with the same name)
        System.out.println(myIntVar); // prints 5

        // If we want to refer to the shadowed myIntVar from this class we need to 
        // refer to it like this:
        System.out.println(this.myIntVar); // prints 0
    }

    public static void main(String[] args){
        new Shadow().shadowTheVar();
    }
}
</syntaxhighlight>

{{Anchor|Java_non_compiling_example}}
However, the following code will ''not'' compile:
<syntaxhighlight lang="java">
public class Shadow {
    public static void main(String[] args){
        int a = 1;

        for(int i = 0; i < 10; i++) {
            // This causes a compilation error since redefining a variable
            // inside a nested block in the same function is not allowed.
            int a = i;
            System.out.println(a);
        }
    }
}

</syntaxhighlight>

=== JavaScript ===
[ECMAScript 6](/source/ECMAScript_6) introduction of <code>let</code> and <code>const</code> with block scoping allow variable shadowing.
<syntaxhighlight lang="javascript">
function myFunc() {
    let my_var = 'test';
    if (true) {
        let my_var = 'new test';
        console.log(my_var); // new test
    }
    console.log(my_var); // test
}
myFunc();
</syntaxhighlight>

==See also==
* [Overloading](/source/Function_overloading)
* [Type polymorphism](/source/Type_polymorphism) 
* [Name binding](/source/Name_binding)

==References==
{{Reflist}}

Category:Variable (computer science)
Category:Programming language comparisons
<!-- Hidden categories below -->
Category:Articles with example C++ code
Category:Articles with example Java code
Category:Articles with example JavaScript code
Category:Articles with example Python (programming language) code
Category:Articles with example Rust code

---
Adapted from the Wikipedia article [Variable shadowing](https://en.wikipedia.org/wiki/Variable_shadowing) by Wikipedia contributors ([contributor history](https://en.wikipedia.org/wiki/Variable_shadowing?action=history)). Available under [Creative Commons Attribution-ShareAlike 4.0 International](https://creativecommons.org/licenses/by-sa/4.0/). Changes may have been made.
