-
Notifications
You must be signed in to change notification settings - Fork 13.1k
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
The Rust Pointer Guide: Section 6 can be made clearer #19067
Comments
That's wrong / doesn't work / is not implemented. There might be a copy even if the function gets inlined. |
This comment seems to disagree. According to the poster it works as described. |
It doesn't: #18363 |
@mahkoh as written, the code does. This is the unoptimised IR of define internal void @_ZN3foo20h9f580e219f1e2e10paaE(%"struct.BigStruct<[]>"* noalias nocapture sret dereferenceable(24), %"struct.BigStruct<[]>"* noalias dereferenceable(24)) unnamed_addr #0 {
entry-block:
%x = alloca %"struct.BigStruct<[]>"*
store %"struct.BigStruct<[]>"* %1, %"struct.BigStruct<[]>"** %x
%2 = load %"struct.BigStruct<[]>"** %x
%3 = bitcast %"struct.BigStruct<[]>"* %2 to i8*
%4 = bitcast %"struct.BigStruct<[]>"* %0 to i8*
call void @llvm.memcpy.p0i8.p0i8.i64(i8* %4, i8* %3, i64 24, i32 8, i1 false)
br label %clean_custom_
return: ; preds = %clean_custom_
ret void
clean_custom_: ; preds = %entry-block
call void @"_ZN20Box$LT$BigStruct$GT$14glue_drop.108817h69e26cab4c19e281E"(%"struct.BigStruct<[]>"** %x)
br label %return
} In particular, there is only one stack slot used which is storing a pointer to |
I'm not saying that there are not (trivial) functions where this will work, e.g., fn f() -> X {
unsafe { std::mem::zeroed() }
} does work as expected without a copy. But this is not what the guide is saying:
This is wrong once Arc::new(f()) is likely to copy the returned value twice: Once from |
I wrote this section under @thestinger 's advisement, I'd like his thoughts here. |
@mahkoh: Correct me if I'm mistaken, but I think the behaviour described here is distinctly different from named return value optimization. The point being made here is that the returned value is immediately placed on the heap and not temporarily on the stack. E.g.: extern crate test;
pub struct X {
x: [u8, ..1 << 10],
}
pub fn f() -> X {
let mut x: X = unsafe { std::mem::uninitialized() };
for i in range(0, x.x.len()) {
x.x[i] = i as u8;
}
x
}
fn main() {
let x = box f();
test::black_box(&x);
} This will only take 1k of stack space + 1k of heap space, instead of 2k of stack space + 1k of heap space as would be the case without this optimization. With named return value optimization it would only take 1k of heap space. |
Update TentHash to version 1.0
Section 6 of The Rust Pointer Guide is as follows:
I was very confused by the second to last paragraph of this section. The paragraph uses the word "that" when referencing a memory location and a pointer. The first reference is clear, but the second isn't. This isn't helped by the fact that in the example the label
x
is used for both the variable passed into the functionfoo()
and the parameter inside the function, making it hard to clearly express where and when values are being assigned. It also says the same thing twiceThe disambiguation should make it clear that both the pointer to x and the pointer to y are being used in the function, where x is explicity passed as a parameter and y is implicitly passed as the return location. The general idea the paragraph expresses is already communicated, but I think it could be more explicit about the mechanics. Currently it almost makes it sound like
foo()
is returning a value via the passed parameter, or that it is moving the value rather than copying from one heap location to another.Also someone mentioned that the "
box" in the second paragraph may be missing another "
".The text was updated successfully, but these errors were encountered: