4 ms·
Yes, but rust on LLVM will also perform NRVO, will it not? NRVO is a compiler optimization, not a feature of the language itself.
by krona 10y ago
Yes, but rust on LLVM will also perform NRVO, will it not?
NRVO is a compiler optimization, not a feature of the language itself.
- banachtarski 10y agoI'm not saying Rust doesn't do this. I'm not familiar with Rust but many languages do NRVO as you point out. The important distinction is whether we actually run additional instructions in this variant of the optimization. In C++ at least, no additional instructions are run.
- lorenzhs 10y agoWell, the C++11 standard requires the Compiler to elide the copy (NRVO) if it wants to, or move if it doesn't want to. The language used is very lawyerish, I had to read the section a couple of times to find it even though I knew it was there (it's mentioned in "Effective Modern C++"). So it's up to the compiler to elide the copy (making it a compiler optimisation as you say), but the standard says that it has to move if it doesn't elide. This means that returning a named loca variable by value is always the best choice. Again, see "Effective Modern C++" for more.
- StephanTLavavej 10y agoCopy elision, including the RVO and NRVO, actually has to be blessed by the language (there is a paragraph in the C++ Standard dedicated to it). That's because copy elision skips calls to copy constructors and destructors, which are "observable" (they can have side effects, including printing stuff to the console, etc.). The general "As If Rule" permission to optimize "unobservable" things away doesn't apply here, so special permission to drop the calls is required. This is true going back to C++98 (C++17 strengthened things with guaranteed copy elision).
- banachtarski 10y agoAh and here's the man I originally learned a lot of these concepts from haha. And TIL. I remember programming back in the C++98 days and people were terrified of the copy on return. I had always assumed there was a reason for it but I suppose people might not have understood the behavior super well or I was misinformed at the time.
- StephanTLavavej 10y agoPart of it was surely programmer confusion, but old compilers in the C++98 days were also worse about implementing the RVO/NRVO. For example, MSVC didn't implement the NRVO until 2005.
- dbaupp 10y agoRust doesn't have user-defined copy constructors and a return is always a move (semantically a memcpy), so I'm not sure it's so relevant as an optimisation for Rust.
- santaclaus 10y agoNRVO is an optimization above a move, at least in C++. Most compilers simply toss a pointer to the returned to 'object' on the call stack for direct manipulation (correct me if I'm mistaken compiler peeps!), avoiding the extra potential internal surgery involved in a move operation.
- echelon 10y agoYou can't manually implement the `Copy` trait?
- Manishearth 10y agoThat makes a type copyable, but does not allow you to insert arbitrary code that must be executed during a copy.
- hornetblack 10y agoKinda but: trait Copy: Clone {} Copy is nearly always done by memcpy/memmove. When Copy is invoked it won't use the `Clone::clone` method: https://is.gd/2hMyNP https://is.gd/2hMyNP. i.e. Clone is always explicit. Added: Essentially Copy is the same as a move, but the original value is still valid.
- masklinn 10y agoYou can but it has no user-defined methods related to it, it's just a marker trait. Move and copy are both straight memcpy, the difference is whether the source remains valid afterwards, not what operation is performed.
- Manishearth 10y agoIt's a language feature if your language has copy and move constructors. Rust doesn't, so it's just an optimization. In C++ the code will have different semantics (e.g. if your move ctors have side effects) based on this optimization, so the language needs to define if/how it works.