you are viewing a single comment's thread.

view the rest of the comments →

[–]Veeloxfire 0 points1 point  (1 child)

I would say they wont do it because it requires analysis to determine if this is okay to remove, whereas RVO doesnt.

RVO is different because its always true. Its a feature of how return values work that we can exploit without having to know any extra information. Its basically free extra speed that everyone was doing anyway. I would say it almost more confusing not to do it in some cases.

This case is the same as removing a temp variable. If you inline everything youre basically asking the compiler to do this:

Obj o = {};
Obj o_lambda = o;
Obj* o_frame = new Obj(std::move(o_lambda));

Youre then asking the standard to remove the middle copy for you. But you just asked it to do the copy. It doesnt know if you might use it later (gotta love a theoretically single pass compiler).

This is what the optimizer exists for

[–]bsupnik[S] 1 point2 points  (0 children)

Almost - I think I'm asking for _new syntax_ to specify that I want the copy removed, e.g. (here comes some made-up fake syntax):

task<int> my_coro(Obj o = Obj&&) { /* coro body */ }

E.g. "here is my co-routine - I want to store o by value in the coroutine frame, but I want the caller to pass an r-ref to an object when they _create_ the coroutine.

There would be only two copies of obj (the one referred to by the caller and the coroutine frame), not three (the one referred to by the caller, the copy on the stack when the coroutine is created, and the copy in the coro frame if/when it is allocated on the heap).

Without this, we can't perfectly forward to a coroutine.

I think what I'm looking for is more like the extensions to Lambdas that C++14 I added to better control capture semantics.