1
0
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 ()

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:
Gergely Risko 2024-05-17 16:07:47 +02:00 committed by GitHub
parent cf057e1965
commit 889a4cbbee
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -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>