How can I trust the compiler for non-guaranteed copy elision (in case of return value optimization) in this example code:
struct X
{
X(const X& src) : size(src.size), very_large_buffer(new char[src.size])
{
memcpy(very_large_buffer, src.very_large_buffer, size);
}
X(X&& src) : size(src.size), very_large_buffer(src.very_large_buffer)
{
}
char* very_large_buffer;
size_t size;
};
X foo()
{
X x;
// some code
return x;
}
X x = foo();
I checked with g++ 11.4 and it does not call copy or move constructor, which means copy elision happens. If I add std::move in the return statement above:
return std::move(x);
Then move constructor is called.
However without std::move, in case the compiler does not decide to do copy elision, the copy constructor will be called, which I would like to avoid.
So how can I both: use compiler’s not guaranteed copy elision (i.e. not to use std::move) and be sure that elision will happen and copy constructor be called?
I mean: in my example I added debug prints and saw that compiler does the elision, but I cannot do this for all my other code. So I would better have copy elision, but if this is not guaranteed, I would much move constructor called, so I need std::move. But if I use std::move copy elision will neve happen. So what is the use of non-guaranteed copy elision then?