3 ms·
If @inbounds wasn't used, then yes, it would throw an error, but @inbounds is specifically for removing those error paths. What happened here is that julia has
by eigenspace 3y ago
If @inbounds wasn't used, then yes, it would throw an error, but @inbounds is specifically for removing those error paths.
What happened here is that julia has a package called OffsetArrays.jl which can be used to create arrays with arbitrary index offsets. Julia arrays start at index 1 (1-based indexing), but with OffsetArrays you could make 0-based arrays, or 10-based arrays or whatever you want.
There happened to be a bunch of code laying around which was older than OffsetArrays.jl and did things like
function f(v::AbstractVector)
for i in 1:length(v)
@inbounds do_something(v[i])
end
end
which implictly assumed that all abstract vectors could be indexed according to normal 1-based indexing rules. This created a lot of silent problems when people then went and fed offset arrays into functions that were using such incorrect indexing schemes.
Instead, modern julia code that works on AbstractArray is supposed to be written using functions like eachindex, or axes, i.e.
function f(v::AbstractVector)
for i in eachindex(v)
@inbounds do_something(v[i])
end
end
though Julia's compiler is now smart enough that using @inbounds like this is typically unnecessary, since it can see that eachindex(v) can't produce an out-of-bounds index.
- renox 3y agoCouldn't this kind of things be caught by type checking? 1-indexed vectors should be different type than arbitrary offset vector (implicitly convertible in one way only).
- eigenspace 3y agoThey are different types, but they share a common supertype (AbstractArray). AbstractArray includes thing like regular Array, and also a whole zoo of other array types (including OffsetArray). The problematic code was incorrectly saying it worked on any subtype of AbstractArray, but was actually written assuming that the arrays were 1-based which is an invalid assumption.