Julia: Lost variable assignment in nested try/catch/finally blocks

Created on 15 Mar 2019  路  5Comments  路  Source: JuliaLang/julia

The following yields (12345, nothing) instead of the expected (12345, 12345):

function foo(b::Bool)
    x = nothing
    try
        try
            x = 12345
            if !b
               throw("hi")
            end
        finally
        end
    catch
    end
    return x
end

foo(true),foo(false)    # (12345, nothing)

For comparison:

function bar(b::Bool)
    x = nothing
    try
        x = 12345
        if !b
           throw("hi")
        end
    catch
    end
    return x
end

bar(true),bar(false)    # (12345, 12345)

function baz(b::Bool)
    x = nothing
    try
        try
            x = 12345
            if !b
               throw("hi")
            end
        catch
        finally
        end
    catch
    end
    return x
end

baz(true),baz(false)    # (12345, 12345)

Related discussions (thanks @JeffreySarnoff for the pointers):
https://discourse.julialang.org/t/try-catch-question/15190/4
https://discourse.julialang.org/t/catching-exceptions-by-type/5690
https://discourse.julialang.org/t/failure-to-catch-an-exception/12822/2

bug

Most helpful comment

While we are here, let's document the in's and out's of try [catch] [finally] end blocks, and the use[s] of each part, the purpose of rethrow and why one would choose to include or exclude either the catch part or the finally part or both. Others know this part of Julia much better than I .. getting the correct info here is reasonable way to migrate it into the docs. :book:

All 5 comments

Using https://github.com/JuliaDebug/JuliaInterpreter.jl:

julia> using JuliaInterpreter

julia> @interpret foo(false)
12345

julia> foo(false)
# nothing

Running with the compiler disabled (with the --compile=no flag) also gives the correct result:

julia> Base.JLOptions().compile_enabled
0

julia> foo(false)
12345

so probably a bug with the optimizer?

While we are here, let's document the in's and out's of try [catch] [finally] end blocks, and the use[s] of each part, the purpose of rethrow and why one would choose to include or exclude either the catch part or the finally part or both. Others know this part of Julia much better than I .. getting the correct info here is reasonable way to migrate it into the docs. :book:

Try catch finally is documented here https://docs.julialang.org/en/v1/manual/control-flow/#The-try/catch-statement-1. While I am sure it can be improved it seems a bit orthogonal to the bug in OP?

This problem seems to first appear in v0.7, so I also suspect an optimizer bug.

Ok -- I am splitting my comment out into a new thread on discourse.

Was this page helpful?
0 / 5 - 0 ratings