Boost logo

Boost :

From: Terje Slettebø (tslettebo_at_[hidden])
Date: 2002-10-12 13:31:05


>From: "David Abrahams" <dave_at_[hidden]>

>>Terje Slettebø <tslettebo_at_[hidden]> writes:

>> I think it would be good to get this patch applied. I looked at
>> operators.hpp a while ago, and found the asymmetric parameters rather
>> inelegant. I.e.:
>>
>> friend const T operator+( T lhs, const T& rhs )
>> {
>> return lhs += rhs;
>> }
>>
>> The patch uses:
>>
>> friend T operator+( const T& lhs, const T& rhs )
>> {
>> T nrv( lhs );
>> nrv += rhs;
>> return nrv;
>> }

>I don't think the fact that the current implementation clashes with
>one person's aesthetics is really a good reason to change it.

True. But as the reasons of performance, enabling NRVO, if present, was
already stated in Daniel's proposal, I didn't include that reason, as well.

>> A couple of things I wonder about:
>>
>> - The posting with the patch
>> (http://lists.boost.org/MailArchives/boost/msg31458.php) says "See also
>> Scott Meyers "More Efficient C++", Item 4.7.". There's no Item 4.7, and
Item
>> 4 doesn't seem to apply, so I wonder what is referred to, here?
>>
>> - The same posting uses "friend const T operator+()" in the posting, but
>> "friend T operator+()" in the patch. Which one will be used, and why?
>>
>> "Effective C++", Item 21, "Use const whenever possible" argues for
returning
>> const UDTs, to avoid operating on temporaries, such as "(a * b)=c". This
>> would also be illegal for built-in types. Why then not return "const T"
in
>> operators.hpp? The const is ignored for built-in types (as they have no
>> "this"), but prevents the operation on temporaries, such as the above.

>In a world of expression template metaprogramming there may be uses
>for operating on the lhs result. Hoever, I'm willing to go with const
>T returns for the next release to see if it raises any alarm bells
>with users.

It seems from later postings in this thread, such as Howard's, that there
may be valid reasons for non-const operations on a temporary.

>> - "More Effective C++", Item 20, "Facilitate the return value
optimization"
>> argues for using the constructor in the return statement, rather than
>> creating a named temp. The argument is that although NRVO is also now
>> possible, RVO (unnamed temporary) has been around longer, and may
therefore
>> be more widely implemented. Thus, compilers implementing NRVO almost
>> certainly implements RVO, but not necessarily the other way around. Given
>> this, why isn't the following used in operators.hpp:
>>
>> friend T operator+( const T& lhs, const T& rhs )
>> {
>> return T(lhs)+=rhs;
>> }
>>

>This is exactly the sort of good question which I felt was unresolved
>before, and which kept me from applying the patch until we had solid
>answers.

Again, Howard's reply shows convincingly that the RVO might in fact be
prevented using the above code. However, according to Daniel's proposal, if
a compiler implements NRVO, then the following might be optimised:

friend T operator+( const T& lhs, const T& rhs )
{
   T nrv( lhs );
   nrv += rhs;
   return nrv;
}

A note, also to Andrei's reply: I only asked why it's not done this way, for
the points I brought up. I didn't say it should be done this way. The
replies I got, that operating on a non-const may be useful, and that the
above code may prevent optimisation, seems reasonable to me.

It's also good that this was brought up, as these points apparently were not
well known.

Regards,

Terje


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