Copy 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).