Boost logo

Boost :

Subject: Re: [boost] [xint] Third release is ready, requesting preliminary review
From: Jeffrey Lee Hellrung, Jr. (jhellrung_at_[hidden])
Date: 2010-05-04 02:03:52


On 5/3/2010 3:52 PM, Chad Nelson wrote:
> On 05/03/2010 06:37 PM, Jeffrey Lee Hellrung, Jr. wrote:
>>> [...] I just realized that, since I have the boost::move calls
>>> wrapped in a #define already, it would be easy to check on that, so
>>> I did. The timings all indicate that without the boost::move() call
>>> for the return values, XInt runs as if Boost.Move weren't even
>>> there. So the boost::move call *is* required to get the benefits of
>>> emulated move semantics, as I originally thought.
>>
>> Sorry, I *definitely* should've added that, as far as I know, RVO
>> generally requires a single, simple return statement. If you have
>> multiple returns, or a return expression more complicated than
>> "return foo;" or "return T(bar,zap);", then I don't think RVO
>> typically kicks in. Can you confirm or deny this to be the case? If
>> it is, then the move(...) calls or COW will almost certainly be
>> necessary to get optimal performance.
>
> In the cases I'm looking at, there are usually only three lines in the
> function: a declaration of an integer to hold the return value, a call
> to a function in the detail namespace to do the operation (with the
> return value object as a parameter), and a return of the return value.
> - From what you're saying, RVO should be easy for the compiler to use, but
> the boost::move call on that return value is still required to get the
> benefits of move semantics.
>
> (That three-line function design is what is preventing the move
> semantics from working as well as they could, I'm pretty sure. I haven't
> had enough time to confirm that yet though.)

Hmmm....can you give a stripped-down example of where you expect (or,
perhaps, where I claim) RVO should kick in, but doesn't?

I tried the following program to test RVO, and emulated the basic
function structure you describe above.
--------------------------------
#include <iostream>

struct X
{
     int x;
     X() : x(0)
     { std::cout << "X::X()" << std::endl; }
     X(const X& other) : x(other.x)
     { std::cout << "X::X(const X&)" << std::endl; }
};

void f(X& x) { x.x = 1; }

X g()
{
     X x;
     f(x);
     return x;
}

int main()
{
     X x = g();
     return 0;
}
--------------------------------

With MSVC9, debug build gives output "X::X()"/"X::X(const X&)", while
release build gives output "X::X()" (i.e., no call to X::X(const X&)).

- Jeff


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk