In many cases when returning a local from a function, RVO 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::move
prevent 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?
Question&Answers:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…