Question

I have a function that looks like this:

// Fetch 1 MB of data
void GetData(std::vector<char> & outData);

The 1MB is exaggerated, but I just want to make the point that it's preferable to avoid unnecessary copies.

If I add this overload:

std::vector<char> GetData()
{
    std::vector<char> result;
    GetData(result);
    return result;
}

Then how likely is it that RVO will kick in?

Was it helpful?

Solution

With most reasonably recent compilers (e.g., VS 2005 or newer, gcc 3.4 or newer), it's essentially certain. I only say "most" because I haven't tested every compiler in existence. Every new compiler I've looked at in probably the last 5 years or so has included it.

OTHER TIPS

RVO will most likely kick in, since it is a pretty simple optimization, which has been available for quite a while. However, in order to give this piece of code real practical value in even moderately high-performance code you'd need NRVO. NRVO is harder to come across, since it is relatively new. Yet it is available. MS compiler, for one example, implements it since VS2005.

I don't think there's any standard answer to this: it depends on your compiler and what it's capable of.

If you're thinking of implementing this for convenience why not just try in on your compiler(s) and either look at the assembly or profile it and see what happens? Empirical evidence about what your compiler actually does is probably better than guessing what some compilers may or may not do.

Then how likely is it that RVO will kick in?

It is a software developer's job to think, not compiler's.

Compilers are generally optimized to make the good code work well - not the bad one.

Personally, I use the first form. Normally with a pointer instead of reference - to highlight the fact that the parameter is the output one, not input.

Also, note that when you say:

std::vector<char> GetData() 
{ 
//   :
    return result; 
}

vector<char> x = GetData();

In the callee, result is copied to a "return value", and then in the caller, the "return value" is copied into x. NRVO can get rid of one of those copies, but not both. The compiler is obliged to call the copy ctor at least once, because it has to assume the copy ctor has side-effects which must be done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top