# Is @inbounds really necessary?

**URL:** https://discourse.julialang.org/t/is-inbounds-really-necessary/5654
**Category:** General Usage
**Created:** [August 31, 2017, 8:00am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654 "2017-08-31T08:00:26Z")
**Posts on this page:** 15
**Page:** 1

<div class="post-metadata">

### Author: ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)
#### Post date: [August 31, 2017, 8:00am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/1 "2017-08-31T08:00:26Z")

</div>

Writing `@inbounds` in code is tedious, and ruins the nice alignment of for loops. Is it really necessary? It feels like in simple loops like

```julia
n = length(x)
for i = 1:n
  x[i] *= 2
end

```

this should be something the compiler could figure out by itself. Is this something that is

- Intrinsically impossible to do even in simple cases
- Tricky to get right because the user might overload `length` and friends
- Intentionally not implemented because it might make development harder
- A planned improvement when somebody gets the time to do it  
?

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 31, 2017, 8:32am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/2 "2017-08-31T08:32:26Z")

</div>

I think it is much better to be explicit with bounds-check removal than to have to constantly think “will the compiler be able to figure out removing the bound checks here”. In addition, bounds check are in the majority of cases a non-issue. It will almost only matter in cases where it inhibits other optimizations, like SIMD.

FWIW, your original example is also better written without a loop, e.g. `x .*= 2` which won’t boundscheck and in addition use SIMD.

---

<div class="post-metadata">

### Author: ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)
#### Post date: [August 31, 2017, 9:20am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/3 "2017-08-31T09:20:08Z")

</div>

I agree that broadcast is best when it can be used, but it’s not always the case.

A lot of package code seems to be littered with `@inbounds`, and it’s recommended in the performance tips, so that it becomes a habit for people to write `@inbounds` everywhere, which makes coding less pleasant. If there was a simple rule like “inbounds is unnecessary on nicely-behaved AbstractArrays when the compiler can prove that the index will be in bounds”, that would remove the burden on the user to worry about `@inbounds` in most cases, and result in code that is either faster (if there was no inbounds) or more pleasant (by removing the inbounds). Tricky loops would still need explicit `@inbounds`.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 31, 2017, 9:40am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/4 "2017-08-31T09:40:24Z")

</div>

> [@antoine-levitt](#):
>
> it becomes a habit for people to write @inbounds everywhere

Well… don’t do that.

> [@antoine-levitt](#):
>
> when the compiler can prove that the index will be in bounds

This is almost impossible to reason about and you would have to add it anyway, just to make sure.

---

<div class="post-metadata">

### Author: ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)
#### Post date: [August 31, 2017, 9:48am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/5 "2017-08-31T09:48:29Z")

</div>

> [@antoine-levitt](#):
>
> it’s recommended in the performance tips, so that it becomes a habit for people to write @inbounds everywhere

It is possible that you misread the relevant part of the [manual](https://docs.julialang.org/en/latest/manual/performance-tips/#man-performance-annotations-1), which claims that

> Sometimes you can enable better optimization by promising certain program properties.

ie that `@inbounds` & co have the _potential_ to improve performance, but of course you have to see for each particular case, with the caveat

> Be certain before doing this. If the subscripts are ever out of bounds, you may suffer crashes or silent corruption.

There is no blanket recommendation to pepper your code with these macros — on the contrary. If you see it in libraries, the best case scenario is that the library author has

1. benchmarked the code and it does improve performance significantly,
2. has checks in place to prevent a segfault (ie the indices are calculated inside the library, or user input is validated).

---

<div class="post-metadata">

### Author: ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)
#### Post date: [August 31, 2017, 1:16pm UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/6 "2017-08-31T13:16:34Z")

</div>

I think the need to be careful is exaggerated: unit tests ignore @inbounds so if you do get a SEGFAULT, that’s more a statement about insufficient unit tests than it is a statement about bad coding.

---

<div class="post-metadata">

### Author: ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)
#### Post date: [August 31, 2017, 1:20pm UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/7 "2017-08-31T13:20:02Z")

</div>

Yeah, it’s not like any other languages have had problems with non-existing bounds checks. Clearly, they should just have written more unit tests. Come on now…

---

<div class="post-metadata">

### Author: ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)
#### Post date: [August 31, 2017, 9:53pm UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/8 "2017-08-31T21:53:29Z")

</div>

There’s also the command line argument `--check-bounds`

[https://docs.julialang.org/en/stable/manual/getting-started/#Getting-Started-1](https://docs.julialang.org/en/stable/manual/getting-started/#Getting-Started-1)

`--check-bounds={yes|no} Emit bounds checks always or never (ignoring declarations)`

---

<div class="post-metadata">

### Author: ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)
#### Post date: [September 2, 2017, 10:30am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/9 "2017-09-02T10:30:59Z")

</div>

I should add that the original example

```julia
n = length(x)
for i = 1:n
  x[i] *= 2
end

```

is definitely not a safe place to use `@inbounds`, as you cannot assume arrays are 1-based. See e.g. [https://docs.julialang.org/en/latest/devdocs/offset-arrays/#Background-1](https://docs.julialang.org/en/latest/devdocs/offset-arrays/#Background-1)

This would be, though:

```julia
for i in linearindices(x)
    x[i] *= 2
end

```

---

<div class="post-metadata">

### Author: ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)
#### Post date: [September 2, 2017, 11:20am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/10 "2017-09-02T11:20:11Z")

</div>

My point was that, in the most common setting of Array (as opposed to general AbstractArray) whose functions are not overloaded, the compiler could recognize that any index between 1 and length(x) is inbounds (and similar for multidimensional iteration, and several other “classical” array types). Of course more general arrays can do crazy stuff, and redefining getindex(Array, Int) leads to nastiness, which means that the compiler would have to detect when those things happen and know about Array, which is ugly and I would understand as a reason why it’s not been implemented. Still, that’s penalizing 99% of uses for the sake of generality.

---

<div class="post-metadata">

### Author: ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)
#### Post date: [September 2, 2017, 11:21am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/11 "2017-09-02T11:21:50Z")

</div>

Still it’s a nice demonstration of the need to be careful with `@inbounds`

---

<div class="post-metadata">

### Author: ![antoine-levitt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/antoine-levitt/32/4008_2.png) [@antoine-levitt](https://discourse.julialang.org/u/antoine-levitt)
#### Post date: [September 2, 2017, 11:25am UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/12 "2017-09-02T11:25:07Z")

</div>

[https://docs.julialang.org/en/release-0.6/manual/performance-tips/](https://docs.julialang.org/en/release-0.6/manual/performance-tips/) still has `@inbounds` for a 1:n loop.

---

<div class="post-metadata">

### Author: ![dlfivefifty](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dlfivefifty/32/1959_2.png) [@dlfivefifty](https://discourse.julialang.org/u/dlfivefifty)
#### Post date: [September 2, 2017, 4:14pm UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/13 "2017-09-02T16:14:59Z")

</div>

> [@kristoffer.carlsson](#):
>
> Yeah, it’s not like any other languages have had problems with non-existing bounds checks. Clearly, they should just have written more unit tests. Come on now…

Other languages don’t turn on bounds checking in the tests.

---

<div class="post-metadata">

### Author: ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)
#### Post date: [September 2, 2017, 7:44pm UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/14 "2017-09-02T19:44:27Z")

</div>

Good point - that is possibly misleading, though it is safe here as the array is created just before, and isn’t an OffsetArray.

---

<div class="post-metadata">

### Author: ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)
#### Post date: [September 2, 2017, 8:35pm UTC](https://discourse.julialang.org/t/is-inbounds-really-necessary/5654/15 "2017-09-02T20:35:25Z")

</div>

[https://github.com/JuliaLang/julia/pull/23565](https://github.com/JuliaLang/julia/pull/23565)
