Skip to content

Commit

Permalink
Document boundscheck macro
Browse files Browse the repository at this point in the history
Fix #20469. [ci skip]
  • Loading branch information
mbauman committed Aug 30, 2017
1 parent 440b18d commit f4d4c8e
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 0 deletions.
42 changes: 42 additions & 0 deletions base/essentials.jl
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,46 @@ section of the Metaprogramming chapter of the manual for more details and exampl
"""
esc(@nospecialize(e)) = Expr(:escape, e)

"""
@boundscheck(blk)
Annotates the expression `blk` as a bounds checking block, allowing it to be elided by [`@inbounds`](@ref).
Note that the function in which `@boundscheck` is written must be inlined into
its caller with [`@inline`](@ref) in order for `@inbounds` to have effect.
```jldoctest
julia> @inline function g(A, i)
@boundscheck checkbounds(A, i)
return "accessing ($A)[$i]"
end
f1() = return g(1:2, -1)
f2() = @inbounds return g(1:2, -1)
f2 (generic function with 1 method)
julia> f1()
ERROR: BoundsError: attempt to access 2-element UnitRange{Int64} at index [-1]
Stacktrace:
[1] throw_boundserror(::UnitRange{Int64}, ::Tuple{Int64}) at ./abstractarray.jl:428
[2] checkbounds at ./abstractarray.jl:392 [inlined]
[3] g at ./REPL[20]:2 [inlined]
[4] f1() at ./REPL[20]:5
julia> f2()
"accessing (1:2)[-1]"
```
!!! warning
The `@boundscheck` annotation allows you, as a library writer, to opt-in to
allowing *other code* to remove your bounds checks with [`@inbounds`](@ref).
As noted there, the caller must verify—using information they can access—that
their accesses are valid before using `@inbounds`. For indexing into your
[`AbstractArray`](@ref) subclasses, for example, this involves checking the
indices against its [`size`](@ref). Therefore, `@boundscheck` annotations
should only be added to a [`getindex`](@ref) or [`setindex!`](@ref)
implementation after you are certain its behavior is correct.
"""
macro boundscheck(blk)
return Expr(:if, Expr(:boundscheck), esc(blk))
end
Expand All @@ -438,6 +478,8 @@ end
Using `@inbounds` may return incorrect results/crashes/corruption
for out-of-bounds indices. The user is responsible for checking it manually.
Only use `@inbounds` when it is certain from the information locally available
that all accesses are in bounds.
"""
macro inbounds(blk)
return Expr(:block,
Expand Down
1 change: 1 addition & 0 deletions doc/src/stdlib/base.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,7 @@ Base.@eval
Base.evalfile
Base.esc
Base.@inbounds
Base.@boundscheck
Base.@inline
Base.@noinline
Base.@nospecialize
Expand Down

0 comments on commit f4d4c8e

Please sign in to comment.