-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
get_unchecked
and friends should do bound checks in debug mode.
#36976
Comments
It's a nice thought, but they cannot change to do this. It would be a breaking change since they are often used to go outside the formal length (i.e. of a vector), but still inside the capacity. |
Not true. |
Plus, if |
Yeah, |
Current use of get_unchecked to go out of bounds of a slice:
It's ubiquitous in the implementation of Vec. Non-libstd code uses the same pattern. It would for example break arrayvec Break syntex If it would be UB to access past the length but inside a capacity, why? |
This code is definitely broken. |
Probably related to the fact that |
It's probably UB because it creates a Granted, references are currently annotated with non-null metadata for LLVM, while they may not be an analogous attribute for "pointee memory is initialized". So it may not get miscompiled today. But it's still super dubious and should get phased out. |
It's a question that the memory model has to answer, whether it is broken or not. |
We can agree that this case is not broken, right, because it points at something that's initialized to a valid value? pub fn truncate(&mut self, len: usize) {
unsafe {
// drop any extra elements
while len < self.len {
// decrement len before the drop_in_place(), so a panic on Drop
// doesn't re-drop the just-failed value.
self.len -= 1;
let len = self.len;
ptr::drop_in_place(self.get_unchecked_mut(len));
}
}
} rust/src/libcollections/vec.rs Lines 553 to 555 in 26d8b6f
|
That use case is indeed not UB. |
That sounds like a good enough reason not to require references to have valid values behind them, as long as the memory behind them is valid. In any case, ATM we do not have any plans of requiring that. |
(Hello, this is my first comment around here). If adding bound checks in debug mode to get_unchecked/get_unchecked_mut is an unacceptable breaking change, then I suggest to add two new methods that do it. This makes the Vec/Slice API bigger, but I think it's worth it. A problem is: how to name those two functions? get_debug_checked/get_debug_checked_mut could be clear, but they seems a bit too much long. |
You’re looking for quite a weird compromise between |
I think it's reasonable to have more checking of (For example, ndarray's corresponding |
That "weird compromise" is essentially how the D language arrays work, they assert bounds in debug builds only. The point of get_unchecked* is to speed up some arrays accesses you're sure are within bounds. The point of the bound tests for the indexing [] syntax is to have a memory safe language. Having those bound tests in debug builds only is indeed an intermediate point between being sure (after proving?) and being conservatively safe (followed by LLVM optimizations that mostly unpredictably remove some bound tests). So in my code where I can't afford bound tests in release builds, I'll keep using bound tests in debug builds. Doing this with a get* plus a debug unchecked_unwrap sounds OK, as long unchecked_unwrap becomes a standard method. |
As shown by a number of examples elsewhere in the thread, that’s not necessarily true (or that it is not always clear which “bounds” the programmer has in mind).
I do not disagree, but I find dubious an idea that many people would use That being said, if we were to add anything here, I’d insist on making it composable somehow (i.e. |
Note that the cases in |
@Aatch Yeah, that's natural, but I still believe that it is wrong to use |
I agree that debug-only checking seems useful but there is a lot of design work remaining here. I am not confident that we can reach consensus on a design without someone spearheading this with an RFC. Some points to make in an RFC related to debug-only checking of unsafe slice indexing:
|
This can help catching a lot of safety issues.
The text was updated successfully, but these errors were encountered: