mirror of
https://github.com/google/comprehensive-rust.git
synced 2025-03-22 23:05:22 +02:00
Fix the debug exercise in the "Borrowing a Value" section (#2083)
Trying to reproduce this RVO shows that actually the optimization that is used here is simple inlining. Once inlining is disabled, the addresses change, even with `-O -C opt-level=3`. The return of the values is also never changed to an "efficient memcpy", but instead was returned on eax+edx, although this result is of course specific to the calling convention of the platform ABI, but no memcpy on the most popular amd64 architecture. I don't think it's educationally important to teach RVO here, so I didn't go into any length trying to force Rust to do a real RVO (passing Point address into the function on the assembly level, so the function can fill in the addition). In my opinion the only important thing is, that if a student is actually clicking the Playground link and looks into the assembly, then our description should match the generated code. That's why I just fixed the content instead of trying to fix the example to be RVO.
This commit is contained in:
parent
cf057e1965
commit
889a4cbbee
@ -35,14 +35,14 @@ slightly to include function arguments and return values.
|
||||
|
||||
# More to Explore
|
||||
|
||||
Notes on stack returns:
|
||||
Notes on stack returns and inlining:
|
||||
|
||||
- Demonstrate that the return from `add` is cheap because the compiler can
|
||||
eliminate the copy operation. Change the above code to print stack addresses
|
||||
and run it on the [Playground] or look at the assembly in
|
||||
[Godbolt](https://rust.godbolt.org/). In the "DEBUG" optimization level, the
|
||||
addresses should change, while they stay the same when changing to the
|
||||
"RELEASE" setting:
|
||||
eliminate the copy operation, by inlining the call to add into main. Change
|
||||
the above code to print stack addresses and run it on the [Playground] or look
|
||||
at the assembly in [Godbolt](https://rust.godbolt.org/). In the "DEBUG"
|
||||
optimization level, the addresses should change, while they stay the same when
|
||||
changing to the "RELEASE" setting:
|
||||
|
||||
<!-- mdbook-xgettext: skip -->
|
||||
```rust,editable
|
||||
@ -63,11 +63,12 @@ Notes on stack returns:
|
||||
println!("{p1:?} + {p2:?} = {p3:?}");
|
||||
}
|
||||
```
|
||||
- The Rust compiler can do return value optimization (RVO).
|
||||
- In C++, copy elision has to be defined in the language specification because
|
||||
constructors can have side effects. In Rust, this is not an issue at all. If
|
||||
RVO did not happen, Rust will always perform a simple and efficient `memcpy`
|
||||
copy.
|
||||
- The Rust compiler can do automatic inlining, that can be disabled on a
|
||||
function level with `#[inline(never)]`.
|
||||
- Once disabled, the printed address will change on all optimization levels.
|
||||
Looking at Godbolt or Playground, one can see that in this case, the return of
|
||||
the value depends on the ABI, e.g. on amd64 the two i32 that is making up the
|
||||
point will be returned in 2 registers (eax and edx).
|
||||
|
||||
</details>
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user