title: Are compilers clever enough to std::move variables going out of scope?
body: <p>Consider the following piece of code:</p>
  
  <pre><code>std::vector&lt;int&gt; Foo() {
      std::vector&lt;int&gt; v = Bar();
      return v;
  }
  </code></pre>
  
  <p><code>return v</code> is O(1), since NRVO will omit the copy, constructing <code>v</code> <a href="https://en.cppreference.com/w/cpp/language/copy_elision" rel="noreferrer">directly in the storage where the function's return value would otherwise be moved or copied to</a>. Now consider the functionally analogous code:</p>
  
  <pre><code>void Foo(std::vector&lt;int&gt; * to_be_filled) {
      std::vector&lt;int&gt; v = Bar();
      *to_be_filled = v;
  }
  </code></pre>
  
  <p>A similar argument could be made here, as <code>*to_be_filled = v</code> could conceivably be compiled to an O(1) move-assign, since it's a local variable that's going out of scope (it should be easy enough for the compiler to verify that <code>v</code> has no external references in this case, and thus promote it to an rvalue on its last use). Is this the case? Is there a subtle reason why not?</p>
  
  <p>Furthermore, it feels like this pattern can be extended to any context where an lvalue goes out of scope:</p>
  
  <pre><code>void Foo(std::vector&lt;int&gt; * to_be_filled) {
    if (Baz()) {
      std::vector&lt;int&gt; v = Bar();
      *to_be_filled = v;
    }
    ...
  }
  </code></pre>
  
  <p>Do / can / is it useful / reasonable to expect compilers to find patterns such as the <code>*to_be_filled = v</code> and then automatically optimize them to assume rvalue semantics?</p>
  
  <hr>
  
  <p>Edit:</p>
  
  <p>g++ 7.3.0 does <em>not</em> perform any such optimizations in -O3 mode.</p>