-
Notifications
You must be signed in to change notification settings - Fork 20
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix bounds check for slicesx.Get #432
Conversation
Use len to ensure the slice doesn't panic on indexing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the point of this was to allow accessing any element in the underlying backing array. Though I suppose we could apply this change and then update other callers that might rely on the old behavior to pass in slice[:cap(slice)]
.
I'll let @mcy make the call on this one.
@jhump this was based on the comment here: #429 (comment) |
Thinking a little more, maybe this is the right change. I guess this was really meant to elide a bounds check for accessing a slice: so instead of having to check the length yourself and then reading Though, now that I'm thinking about it, is the after-the-fact bool check really cheaper than the before-the-fact range check? I think they both boil down to a Edit: Is the bool check maybe cheaper because it doesn't have to (re)load the slice's length? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is the correct change, yes.
Incidentally, I thought I had updated this file with a more efficient version of the bounds check. As Go generates this code, because the compiler is dumb, it generates two branches, even though it can be done with one. Notably, the idx < 0
bit is redundant, because Go guarantees that cap(s) < math.IntMax
, and negative values compare as greater than math.IntMax
when compared unsigned. When I originally wrote this, I assumed the Go compiler was not dumb and would know it could merge these branches, but I guess I gave it too much credit.
Also I can't immediately remember why I made Get not call GetPointer?
Get not call GetPointer is one less branch. |
This changes
slicesx.Get
andslicesx.GetPointer
to check the idx is within the length of the slice not the capacity. This avoids accessing slice data that is outside the slice length, allowing the use ofslicesx.Get
as a bonds check for indexing into a slice.