In many cases when returning a local from a function, RVO (return value optimization) kicks in. However, I thought that explicitly using std::move would at least enforce moving when RVO does not happen, but that RVO is still applied when possible. However, it seems that this is not the case.
#include "iostream"
class HeavyWeight
{
public:
    HeavyWeight()
    {
        std::cout << "ctor" << std::endl;
    }
    HeavyWeight(const HeavyWeight& other)
    {
        std::cout << "copy" << std::endl;
    }
    HeavyWeight(HeavyWeight&& other)
    {
        std::cout << "move" << std::endl;
    }
};
HeavyWeight MakeHeavy()
{
    HeavyWeight heavy;
    return heavy;
}
int main()
{
    auto heavy = MakeHeavy();
    return 0;
}
I tested this code with VC++11 and GCC 4.71, debug and release (-O2) config. The copy ctor is never called. The move ctor is only called by VC++11 in debug config. Actually, everything seems to be fine with these compilers in particular, but to my knowledge, RVO is optional.
However, if I explicitly use move:
HeavyWeight MakeHeavy()
{
    HeavyWeight heavy;
    return std::move(heavy);
}
the move ctor is always called. So trying to make it "safe" makes it worse.
My questions are:
- Why does std::moveprevent RVO?
- When is it better to "hope for the best" and rely on RVO, and when should I explicitly use std::move? Or, in other words, how can I let the compiler optimization do its work and still enforce move if RVO is not applied?
 
     
     
     
    