More effective C + +----(20) assists in the completion of return value optimization

Source: Internet
Author: User

Item M20: Assist to complete return value optimization
a function that returns an object is difficult to be efficient, because the return of a value results in the construction and destructor within the calling object (see clause M19), which cannot be avoided. The problem is simple: a function either returns an object to ensure proper behavior or does not. If it returns an object, there is no way to get rid of the object being returned. That's what I'm talking about.
Consider the member functions of the rational (rational) class operator*: (The return type is const to prevent successive manipulation of the operator, one is that the returned object is a temporary object, multiple operations are on its temporary object, and two are not compliant with the built-in type)

Class Rational {public:  rational (int numerator = 0, int denominator = 1);  ...  int numerator () const;  int denominator () const;}; For an explanation of why the return value is const, see the terms m6,const Rational operator* (const rational& LHS,                         const rational& RHS);

article m6
Without even looking at the operator* code, we knew it was going to return an object because it returned the result of two arbitrary numbers. These results are arbitrary numbers. How can operator* avoid creating new objects to accommodate their computational results? This is not possible, so it has to create a new object and return it. However, C + + programmers still spend a lot of time looking for legendary methods to remove objects returned by values (see effective C + + clause 23 and clause 31).
Sometimes people return pointers, which leads to this comical syntax:

An unreasonable method to avoid returning an object const rational * operator* (const rational& LHS,                           const rational& RHS); Rational a = 10; Rational B (1, 2); Rational C = * (A * b);             Do you think this is "normal"?

It also raises a problem. Should the caller delete a pointer to the function return object? The answer is usually yes, and often leads to resource leaks.
Some other developers will return a reference. This method produces an acceptable syntax,
A dangerous (and incorrect) method to avoid returning the object Const rational& operator* (const rational& LHS,                          const rational& RHS); Rational a = 10; Rational B (1, 2); Rational C = A * b;                          It looks reasonable.

However, the function cannot be implemented correctly. One way to try this is to:

Another dangerous method (and incorrect) method used to//avoid returning the object Const rational& operator* (const rational& LHS,                          const rational& RHS) { C4/>rational result (Lhs.numerator () * Rhs.numerator (),                  lhs.denominator () * Rhs.denominator ());  Return Result;//wq the object that it points to does not already exist when the raise returns

The reference returned by this function does not already exist for the object it points to. It returns a reference to the result of the local object, and the result is automatically freed when operator* exits. Returns a reference to an object that has been disposed, which is absolutely not available. ( return to *this, refer to C + + Primer
Trust me: Some functions (operator* also in it) must return an object. This is how they operate. Don't fight, you won't win.
Your effort to eliminate the value returned by the object will not win. It was a wrong war. from an efficiency standpoint, you should not care about the object returned by the function, you should only care about the object's overhead. What you should be concerned about is directing your efforts to finding ways to reduce the cost of returning objects rather than eliminating the object itself (we now realize that this quest is useless). If there is no overhead associated with these objects, who cares how many objects are being built?
Returning an object in some way allows the compiler to eliminate the overhead of the temporary object, which is generally common. The trick is to return constructor argument instead of returning the object directly,You can do this:

An efficient and correct method for implementing//returning the function of the object const Rational operator* (const rational& LHS,                         const rational& RHS) {  return Rational (Lhs.numerator () * Rhs.numerator (),                  lhs.denominator () * Rhs.denominator ());

Carefully observe the returned expression. It looks as if it is invoking rational's constructor, which is actually the case. You create a temporary rational object with this expression,
Rational (Lhs.numerator () * Rhs.numerator (),         lhs.denominator () * Rhs.denominator ());

And this is a temporary object, the function copies it to the function's return value.
Returning constructor argument without a local object, this method also brings you a lot of overhead, because you still have to pay for the construction and release of the temporary object within the function, and you still have to pay for the structure and release of the function return object. But you've got the benefits. C + + rules allow the compiler to optimize for temporary objects that do not appear (temporary objects out of existence). So if you call operator* in the following environment:

Rational a = 10; Rational B (1, 2); Rational C = A * b;                          Call operator* here

The compiler is allowed to eliminate temporary variables within the operator* and the temporary variables returned by operator*. They can construct the object defined by the return expression in memory allocated for Target C. If your compiler does this, the overhead of calling operator* 's temporary object is 0: No temporary objects are created. your price is to call a constructor-the constructor that is called when you build C. And you can't do better than this, because C is a named object and the named object cannot be eliminated (see clause M22)。 But you can also eliminate the call cost of operator* by declaring the function as inline (but first see effective C + + clause 33):

The most efficient-to-write a function returning//an objectinline const Rational operator* (const rational& LHS ,                                const rational& RHS) {  return Rational (Lhs.numerator () * Rhs.numerator (),                  lhs.denominator () * Rhs.denominator ());}

"Well, good," you muttered, "optimizer, who cares what the compiler can do?" I want to know what they did, Does any of the nonsense work with real compilers? " It does. This particular optimization- eliminating local temporary objects by using the return position of the function (or replacing it with an object in the function's called location) is well known and universally implemented. It even has a name: return value optimization (return optimization)(Wq raise: In the Deep Exploration of C + + object model, there is more detail about it, which is called Named Return value optimization.) Note, however, that this optimization is not valid for a normal assignment operation, and the compiler cannot replace the assignment operation with a copy constructor, and the final conclusion is that there is no better optimization possible in order to ensure the correct semantics of the preceding question. In fact, this optimization has its own name to explain why it is widely used. Programmers looking for C + + compilers will ask the vendor if the compiler has a return value optimization feature. If one seller says yes and the other asks, "What is that?" ", the first seller will have a clear competitive advantage. Ah, capitalism, sometimes you really should love it. (on behalf of the author's point of view, the translator strongly advocates four cardinal principles translator:-))
Report:
The last paragraph in the text how to translate, I am somewhat unsure, please master informed, in order to easily understand, I enclose this article in the last paragraph of the English original:
"Yeah, Yeah," You Mutter, "optimization, schmoptimization. Who cares what compilers can do? I want to know what they does do. Does any of the nonsense work with real compilers? " It does. This particular optimization-eliminating a local temporary by using a function's return location (and possibly replacing That with a object at the function's call site)-is both well-known and commonly implemented. It even has a name:the return value optimization. In fact, the existence of a name for this optimization could explain why it's so
Widely available. Programmers looking for a C + + compiler can ask vendors whether the return value optimization is implemented. If one vendor says yes and another says "The What?," the first vendor have a notable competitive advantage. Ah, capitalism. Sometimes just gotta love it.

Summary: return value Optimization!

More effective C + +----(20) assists in the completion of return value optimization

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.