0

I am trying to familiarize my self with the std::unique_ptr and I understand that these pointers can only be moved. This is the code that I am trying out

struct foo
{
    int a;
};

std::unique_ptr<foo> GetPointer()
{
    std::unique_ptr<foo> f(new foo());
    return f;
}

int main()
{
    std::unique_ptr<foo> m = GetPointer();
}

I am using the flag -fno-elide-constructors to disable compiler optimization that reduces the copies made. My question is why is the f being returned ? It is an lvalue so I am assuming it cannot be moved. I was expecting to get an error because of return f and I was under the impression it should be return std::move(f)

MistyD
  • 16,373
  • 40
  • 138
  • 240
  • I am trying this out on coliru with the following `g++ -std=c++11 -fno-elide-constructors -O2 -Wall -pedantic -pthread main.cpp && ./a.out` – MistyD Jul 02 '15 at 04:54
  • 1
    This is also covered as part of [this answer](http://stackoverflow.com/a/11540204/962089), which has a ton of information on move semantics if you need it. – chris Jul 02 '15 at 04:54
  • @chris I don't think the question is just about moving a unique pointer. It looks like the OP wanted this to *fail*, and tried to make it so via disabling elided constructions, yet it still works. Further, the linked duplicate's selected answer beautifully covers copy elision and rvo, but again, it looks like the OP was trying *not* to do that. – WhozCraig Jul 02 '15 at 04:56
  • Yes i was expecting to get a compilation error however the above code compiled successfully. Why is that ? – MistyD Jul 02 '15 at 05:01
  • @MistyD The answer chris linked is amazing. Scroll down to the `Moving out of functions` section. – WhozCraig Jul 02 '15 at 05:05
  • @WhozCraig, The section you stated really does spectacularly cover why this fails. *If a function returns by value, some object at call site is initialized with the expression after the return statement as an argument to the move constructor* and *C++11 has a special rule that allows returning automatic objects from functions without having to write std::move* in particular. – chris Jul 02 '15 at 05:08
  • Thanks for clearing that up. Yes that explains it. Now I wonder if `-fno-elide-constructors` works only with copy constructors and does not affect move semantics – MistyD Jul 02 '15 at 05:10
  • @MistyD, The compiler can still elide moves. Returning a large `std::array` by value works much better with an elided move because moving a `std::array` still requires copying everything. – chris Jul 02 '15 at 05:13
  • @chris Joseph M. touches on it as well in a comment under the selected answer linked as a duplicate here, but the answer you linked (authored by fred as well, go figure) is absolutely amazing. Thanks for that!. That thing should be a chapter in a book somewhere. – WhozCraig Jul 02 '15 at 05:16
  • 1
    @WhozCraig, I suppose that's what you get from someone who actually teaches :) – chris Jul 02 '15 at 05:21

0 Answers0