The Complete Guide to `return x;` - Arthur O'Dwyer - [CppNow 2021]
HTML-код
- Опубликовано: 6 ноя 2024
- #Boost #Cpp #CppNow
Slides: cppnow.org/his...
CppNow Website: cppnow.org
CppNow Twitter: @CppNow
Streamed & Edited By Digital Medium Ltd: events.digital...
------
Join Arthur O'Dwyer on a deep dive into Return Value Optimization, implicit move, and related topics. We'll start with an explanation of the calling convention on a typical machine, showing where the mysterious "return slot" lives, and why it makes sense that C++03 allowed copy elision in certain special cases (but not others). Then we'll show how C++11 (and a subsequent defect report) upped the game by quietly turning the remaining copies into moves, so that the received wisdom these days is that `return std::move(x)` is never necessary and often a pessimization (because it disables RVO). However, even in C++17, `return x` would sometimes quietly copy a large object instead of moving it. C++20 adopted Arthur's P1155 "More Implicit Moves," which means that many of these cases have been fixed. Arthur will show one or two cases that remain troublesome.
Furthermore, C++20 adopted David Stone's P0527 "Implicitly move from rvalue references." This paper is a core-language game-changer: it permits `return x` to move out of the target of `x` when `x` is an rvalue reference. We'll show how this surprising new feature of C++20 can be used in the "perfect returning idiom." ...Or can it? We'll review various late-breaking issues surrounding implicit move and the solutions proposed in Arthur's P2266 "Simpler Implicit Move."
------
Arthur O'Dwyer
Arthur O'Dwyer is the author of "Mastering the C++17 STL" (Packt 2017) and of professional training courses such as "Intro to C++," "Classic STL: Algorithms, Containers, Iterators," and "The STL From Scratch." (Ask me about training your new hires!) Arthur is occasionally active on the C++ Standards Committee and has a blog mostly about C++. He is also the author of "Colossal Cave: The Board Game," an avid club juggler, and the recipient of four
------
May 1, 2022 - May 6, 2022 - Aspen, Colorado
-------------------------
---
*--*
---
Arthur is one of my favorite speakers on C++. Not only are they informative they are engaging and entertaining.
Really good compele guide to a NRVO, rvalues and much more. No fillers, just packing with technical stuff. Great talk.
the x64 calling convention is that the first 6 or so parameters are passed through registers. on x86 everything goes through the stack.
Very interesting thank you for putting this together
Glad you enjoyed it
42:40 I believe the warnings an -Wpessimizing-move and -Wredundant-move, but as Arthur said, C++20 just deals with this directly.
Question about slide 71, int && h() { int x = 42; return x;} is it not true that this is OK according to reference lifetime extension? (although ok maybe pathological code), what do you think about reference lifetime extension? Is there a reason for it to exist if move semantics are done properly?
37:50 what is decltype(auto)? Why can't you just use auto here? I would expect "decltype(t.foo()) x = t.foo();" or "auto x = t.foo();" What is the reason for "decltype(auto)" and what does it mean?
`decltype(auto)` means "the undecayed type of the right-hand side," whereas `auto` alone means "the decayed type of the right-hand side." So on slide 42, `auto x = B().foo()` would be like `B x = B().foo()`, but `decltype(auto) x = B().foo()` would be like `B& x = B().foo()`. `decltype(auto)` means the same thing as `decltype(t.foo())` in this case.
The more common use of `decltype(auto)` is as a return type. For example, `template decltype(auto) firstelt(T&& t) { return std::get(std::forward(t)); }` means [almost] the same thing as `template auto firstelt(T&& t) -> decltype(std::get(std::forward(t))) { return std::get(std::forward(t)); }` but is a lot less typing. ["Almost": the difference is that the latter is SFINAE-friendly.]
Add a move constructor to auto_ptr? Why? It has been removed from the standard in C++17 already...
Slide 72:
Why this should not compile? Isn't RVO kick in here?
Yes, all else being equal, this is a place NRVO could kick in. But there's a trick with NRVO, implied by its formal name "copy elision." When NRVO happens, we're not saying there's *no* copy! We're saying that semantically there *is* a copy; it's just that the compiler is allowed to optimize by eliding it. We're still eliding some *thing*, and the compiler still has to figure out what that thing is. In general, if class X's copy constructor is =delete'd, then you're not allowed to return X objects by copy - not even if the copy would go on to be elided. And on slide 72, since struct auto_ptr has no constructor from an xvalue auto_ptr, then you're not allowed to return x (as a move-eligible id-expression) by move - not even if the move would go on to be elided.
Very bad analogy: It's kind of like, you're trying to buy a copy operation, and NRVO gives you a coupon for "100% off" the *price* of a copy operation; but if there are no suitable copy operations "in stock" at the copy store, then merely having the coupon doesn't help.
The conclusion about the Ambig case is incorrect. In [over.match.general], "If a best viable function exists and is unique, overload resolution succeeds and produces it as the result. Otherwise overload resolution fails...". Ambiguity is a failure of overload resolution, so the second round kicks in and succeeds, making the program well-formed. The behavior of GCC, Clang and MSVC is conformant.
@49:27 - I don't think I really make any "conclusion" about this example, let alone an "incorrect" conclusion; I merely say that I understand how the wording circa May 2021 was easy for vendors to disagree about. In this video I don't think I even bothered to name the Big Four vendor who disagreed - but in P2266 ( www.open-std.org/jtc1/sc22/wg21/docs/papers/2022/p2266r3.html#two-resolutions ) I did: it was EDG. :) Happily, since P2266 was adopted for C++23 ( github.com/cplusplus/draft/commit/d696d9482c0c738a8131ee0089ed7e4484240240 ), the whole example is obsolete. As of September 2023, the only Big Four vendor who's non-conforming on this example is MSVC ( godbolt.org/z/ha9o97cK8 ).