1

According to C++ standard:

Copy elision is one of the two allowed forms of optimization, alongside allocation elision and extension, (since C++14)

And if I recall correctly, copy elision is only allowed in return, throw, catch, and yield statement.

In that case, for code like this:

void func(type x)
{
    auto y = bar();

    // do something with y

    x.foo = y; // Can this be optimized?

    return;
}

Is it theoretically permitted by the standard for compiler to use move constructor on lvalue y (potentially by converting it to xvalue implicitly) suppose the compiler is smart enough to figure out that the conversion is safe/equivalent (unlike the corner case mentioned in this answer).

Lifu Huang
  • 11,930
  • 14
  • 55
  • 77
  • *Can this be optimized?* No. *Should I always use `std::move()` for the last usage of a local L-value?* Mostly. – L. F. Sep 12 '20 at 01:51
  • Thank you @L.F.! I would to learn more if you could expand a bit on your comment. e.g. why last usage like this cannot be optimized? Is it because of some technical hard blocker or simply for compatibility with existing compiler implementation? – Lifu Huang Sep 14 '20 at 23:24
  • @LifuHuang although the dupe doesn't ask quite the same question I think you will find it will answer all of your doubts – bolov Sep 14 '20 at 23:25
  • Thank you @bolov for providing the link. While I do understand there are cases where the last usage of local variable can NOT be optimized by an automatic conversion to r-value (just like how compiler won't respect all `inline`). My question is different from the dupe because I want to understand is it ALLOWED for a compiler to do such optimization in the future suppose it's smart enough to figure out it's not a corner case? Edited my answer to reflect my original intention. Thanks! – Lifu Huang Sep 14 '20 at 23:35
  • @LifuHuang the dupe does answer that: no, it cannot because there cannot exist a consistent rule to determine the last usage of a variable. – bolov Sep 14 '20 at 23:51
  • 1
    there is work done (I think by Herb Sutter) on a proposal to add "kinds" of parameters like `in` `out` `forward` and `forward` would allow just one use and that would be move by default. – bolov Sep 15 '20 at 00:13
  • 1
    Some other languages (e.g., Rust) do take the ownership of `y` (i.e., move from `y`) in an access like `x.foo = y;`, and prevent any further use of `y` at compile-time. C++, however, does not provide such guarantees except in a few limited cases (e.g., `return`), so copying is invoked in most cases. It is theoretically possible to revise the standard to allow such optimizations, but the benefit doesn't seem to justify the cost, complexity, and inconsistency. – L. F. Sep 15 '20 at 10:09

0 Answers0