-
Notifications
You must be signed in to change notification settings - Fork 15
assume no "pointer arithmetic" performed on an &T
#19
Comments
That makes me very uncomfortable. You have an object of the correct size, and you're accessing it through a pointer which is safely derived. |
Hm; that implies either a much stricter handling of pointers in In particular, in C, it's defined so long as the (offset) pointer is still part of the same "object" (read: allocation), while this model basically introduces a subtyping relation on "objects" (in the C sense). One pattern this would break hard is
|
I use a variant of |
This code which does not cross function boundaries does a very similar thing: let mut s = Struct { x: 0, y: 1, z: 2 };
let p: *mut i32 = &mut s.x;
*p.offset(1) += 1; And yet I feel differently at fn boundaries. I think this is because I think about functions in terms of permissions. Having a safe function like this: pub fn foo(p: &mut i32) {
let q: *mut i32 = p;
*q.offset(1) += 1;
} seems completely and obviously wrong. It exceeds the permissions that was given to it (which applied to I think before we are going to be able to settle any of these kinds of questions, we have to lay out the higher-level views that we are coming from and try to reach some agreement there. |
I don't think function boundaries should do anything (beyond create an extra scope), for UB purposes. If people are pulling things out into functions, their code must not become undefined, IMHO. |
I imagine this concerns only Could these |
I'll note that I want this to be enabled - I'm just not sure how viable it is given existing code. @Amanieu: In the specific case of intrusive containers, how viable would it be to, instead of having |
@eternaleye That doesn't work since a |
After looking through my code a bit, I don't think it will be affected by this since it uses |
I would argue this is yet another instance of how closely we "trust types", just with opposite "polarity". In the blog post, Niko discussed whether inside the body of a function that takes A function that takes a It seems to me that whether the compiler is allowed to rely on this assumption ("functions that need more than is given by their arguments are unsafe") for optimizations again depends on whether this is an "unsafe context" or not -- generally, we want such optimizations as there is some potential for producing faster code, but for people writing unsafe code this may be a very dangerous prospect. |
I am pretty sure that this is not allowed in C -- see e.g. this formalization of the C object memory model, which clearly forbids the original code. In Rust, Stacked Borrows proposes to forbid this. Some related issues:
I will close this issue since the above seem to cover the relevant aspects. |
It is a very powerful optimization for us to assume that the function
foo
here cannot accessa
orc
:@pcwalton reports that by default in C or C++ -- or at least in LLVM -- it would be legal to have a function like this:
and then to invoke it on
foo(&x.b)
in a similar scenario.Telling LLVM to assume that Rust functions don't play such games appears likely to have a significant impact on our ability to optimize. I'll report some numbers when @pcwalton is more sure of them. :)
The text was updated successfully, but these errors were encountered: