# Possible compiler bug with shadowed global variable

**URL:** <https://discourse.julialang.org/t/possible-compiler-bug-with-shadowed-global-variable/110362>\
**Category:** New to Julia\
**Tags:** bug, potential-bug\
**Created:** [February 18, 2024, 12:58am UTC](https://discourse.julialang.org/t/possible-compiler-bug-with-shadowed-global-variable/110362 "2024-02-18T00:58:21Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![binarycat](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/binarycat/32/207110_2.png) [@binarycat](https://discourse.julialang.org/u/binarycat)\
**Post date:** [February 18, 2024, 12:58am UTC](https://discourse.julialang.org/t/possible-compiler-bug-with-shadowed-global-variable/110362/1 "2024-02-18T00:58:21Z")

</div>

global z = 12  
begin  
print(z)  
local z = 10  
end

this gives an undefined variable error.

this type of backwards-reaching compile error is extremly unusual, and there could be hundreds of lines of code between the the derefrence and the local.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [February 18, 2024, 1:07am UTC](https://discourse.julialang.org/t/possible-compiler-bug-with-shadowed-global-variable/110362/2 "2024-02-18T01:07:09Z")

</div>

> [@binarycat](#):
>
> global z = 12  
> begin  
> print(z)  
> local z = 10  
> end

You are not creating a local scope here. If you do use a local scope by using `let` instead of `begin` then you get an `UndefVarError`.

```julia-repl
julia> global z = 10
       let
           println(z)
           local z = 12
       end
ERROR: UndefVarError: `z` not defined
Stacktrace:
 [1] top-level scope

```

The issue I see is that `local` does not cause an error whem at the top-level.

Edit: Actually, there is some unexpected behavior here I did not expect.

```julia-repl
julia> global z = 10
       begin
           local z = 12
           println(z)
       end
       println(z)
12
10

```

[https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Global-Scope](https://docs.julialang.org/en/v1/manual/variables-and-scoping/#Global-Scope)

> If a top-level expression contains a variable declaration with keyword local, then that variable is not accessible outside that expression. The variable inside the expression does not affect global variables of the same name.

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [February 18, 2024, 4:36am UTC](https://discourse.julialang.org/t/possible-compiler-bug-with-shadowed-global-variable/110362/3 "2024-02-18T04:36:42Z")

</div>

> [@mkitti](#):
>
> If a top-level expression contains a variable declaration with keyword local, then that variable is not accessible outside that expression. The variable inside the expression does not affect global variables of the same name.

Full discussion in [issue 10472](https://github.com/JuliaLang/julia/issues/10472), but long story short, declaring local variables in a globally scoped top-level expression is useful for pasting code from functions into the REPL and for macros making temporary variables but keeping the input code in its original scope without knowing if it’s local or global. Apparently a breaking macro hygiene change could get around this oddity, but it’d just complicate things. If it weren’t for making macros work on the global scope, I’d never do this, I’d rather declare select global variables in a local scope where variables are local by default.

> [@binarycat](#):
>
> this type of backwards-reaching compile error

`local` and `global` declarations occur across the entire enclosing expression no matter where you put them, so they don’t let you swap variable scope line by line. `print(z)` errored because you didn’t assign `local z` a value by that point.

> [@binarycat](#):
>
> global z = 12

This declaration is unnecessary if the pasted code is already in the global scope. Aside, post code between triple backticks ```` lines of code ```` to for monospaced code formatting.
