# @view : No bound checkings?

**URL:** <https://discourse.julialang.org/t/view-no-bound-checkings/108068>\
**Category:** New to Julia\
**Tags:** views\
**Created:** [December 26, 2023, 6:47pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068 "2023-12-26T18:47:44Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![hlbnet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hlbnet/32/204549_2.png) [@hlbnet](https://discourse.julialang.org/u/hlbnet)\
**Post date:** [December 26, 2023, 6:47pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/1 "2023-12-26T18:47:44Z")

</div>

I am trying the following code.

```julia
v = Vector{Int8}(1:10)
w = @view v[3:8]
deleteat!(v, 3:8)
println(v)
w[4] = 42
println(w)

```

The result is this:

```julia
Int8[1, 2, 9, 10]
Int8[9, 10, 0, 42, 7, 8]

```

My question is about the second printed line, which is the content of the view w after a deletion in v and an assignation in w.  
Are the values actually found in the view w predictable in some way, or are they garbage ?  
Where is the 42 actually stored ?  
Is there a risk of memory corruption with this kind of action ?

---

<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:** [December 26, 2023, 7:17pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/2 "2023-12-26T19:17:27Z")

</div>

The numbers are reproducible due to the implementation details of `deleteat!`. The original memory is not reallocated so it still exists. `deleteat!` just shifts values from the end down and fills the next spot with a zero.

The main danger would be a segmentation fault. That is accessing memory that Julia did not allocate.

It’s probably a bug. The bounds check should occur on the original array. Instead it seems to occur on the `SubArray`’s original indices.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 26, 2023, 7:53pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/3 "2023-12-26T19:53:12Z")

</div>

Would be great to have an issue for this.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [December 26, 2023, 7:54pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/4 "2023-12-26T19:54:03Z")

</div>

is it a bug? doesn’t the docstring of `view` specifically say that the parent array can’t be modified and explains the bounds checking behavior?

> The behavior is undefined if the shape of the parent array is changed after view  
> is called because there is no bound check for the parent array; e.g., it may  
> cause a segmentation fault.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 26, 2023, 7:58pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/5 "2023-12-26T19:58:02Z")

</div>

I would expect that the `deleteat!` call should throw since the indices are out of bounds. Unless the contract is actually that you can delete already out of bounds indices, which is possible (I may recall wrongly) but would surprise me a bit.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 26, 2023, 8:41pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/6 "2023-12-26T20:41:25Z")

</div>

> [@StefanKarpinski](#):
>
> would expect that the `deleteat!` call should throw since the indices are out of bounds.

Why? The `deleteat!` call is on the vector `v`, not the view `w`. It’s perfectly in bounds.

---

<div class="post-metadata">

**Author:** ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)\
**Post date:** [December 26, 2023, 8:47pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/7 "2023-12-26T20:47:51Z")

</div>

Oh, hah, I assumed it was v for view. Carry on.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 26, 2023, 9:09pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/8 "2023-12-26T21:09:43Z")

</div>

Ultimately, I think this means that views shouldn’t assume to be inbounds after creation, since the parent vector could have changed size. Its boundscheck can’t, in general, be removed anymore (unless the parent is a `Memory`, not a `Vector` - I guess the same holds for `Matrix`).

We could fix this by making the view wrap the `Memory` of the parent instead, in which case removing the bounds check on indexing stays legal, because those can’t shrink in size.

Quite unfortunate, since that will cause a lot of code where the parent needs to be a `Vector` to become slower.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [December 26, 2023, 9:15pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/9 "2023-12-26T21:15:44Z")

</div>

> [@Sukera](#):
>
> since the parent vector could have changed size.

if the parent vector changes size, all bets are off for any sane behavior of existing views. I think that’s just something users need to be aware of and is not a mistake with the current design

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 26, 2023, 11:15pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/10 "2023-12-26T23:15:24Z")

</div>

How should someone that is aware of this change their code to prevent that issue though? Say you write some library that takes in a `Vector` and you take views of that vector in your library. Unbeknownst to you, the caller has another task running where they change the vector length. Under the assumption that the vector doesn’t change size, your library is correct & safe, but if the size can change, your previously safe code is now incorrect & _unsafe_ because of code you had no control over. That’s a recipe for not only segfaults, but security exploits. I’m having a hard time coming up with code that prevents this, short of not using views in your library.

If we change views to instead apply to the `Memory` the vector originally referenced, this will still be safe and not segfault because the memory can’t suddenly change size out from under you.

---

<div class="post-metadata">

**Author:** ![adienes](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adienes/32/37459_2.png) [@adienes](https://discourse.julialang.org/u/adienes)\
**Post date:** [December 26, 2023, 11:53pm UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/11 "2023-12-26T23:53:37Z")

</div>

> [@Sukera](#):
>
> your previously safe code is now incorrect & _unsafe_ because of code you had no control over.

“your” (package developer) code isn’t incorrect

“your” (user) code is incorrect. I don’t think package devs can be expected to save users from themselves if they are trying to do something as obviously dangerous as asynchronous modification of backing memory to array views

---

<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:** [December 27, 2023, 3:10am UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/12 "2023-12-27T03:10:01Z")

</div>

```julia
function getindex(V::FastContiguousSubArray{<:Any, 1}, i::Int)
    @inline
    @boundscheck checkbounds(V, i)
    @inbounds r = V.parent[V.offset1 + i]
    r
end

```

Here is the `getindex` in question at least for a single index. The `@inbounds` is problematic. Perhaps we could fix this by specializing `checkbounds` for `SubVector`?

```julia
function checkbounds(A::SubArray{<:Any,1}, i::Int)
    @inline
    checkbounds(Bool, A, i) || throw_boundserror(A, I)
    checkbounds(Bool, A.parent, A.offset1 + i) || 
        throw_boundserror(A.parent, A.offset1 + i)
    nothing
end

```

You can still elide the bounds check through the normal mechanisms.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [December 27, 2023, 7:13am UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/13 "2023-12-27T07:13:54Z")

</div>

> [@adienes](#):
>
> “your” (user) code is incorrect. I don’t think package devs can be expected to save users from themselves if they are trying to do something as obviously dangerous as asynchronous modification of backing memory to array views

There doesn’t have to be a “user program” involved here. For example, consider a web server that has a concurrency bug on some vector where an operation uses those views that’s triggerable through requesting some end points in a particular way. If this were to throw an error instead of segfault, you’d get a nice, isolated aborted request and could otherwise carry on. With a segfault however, you either crash the whole server or worse, actively give an attack vector to a malicious user of your web service, all triggered by a concurrency bug that led to being a safety issue.

I think it’d be good to prevent these things by design, by ensuring that views are as safe as they can reasonably be.

---

<div class="post-metadata">

**Author:** ![hlbnet](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hlbnet/32/204549_2.png) [@hlbnet](https://discourse.julialang.org/u/hlbnet)\
**Post date:** [December 27, 2023, 9:04am UTC](https://discourse.julialang.org/t/view-no-bound-checkings/108068/14 "2023-12-27T09:04:01Z")

</div>

Thanks everybody for your analysis.  
My understanding so far, based on answers, is that the use of views on an array is unsafe and may lead to memory corruption if the array is resized.  
That is good to know in my learning trip …
