Clang ++ optimized return code

Source: Internet
Author: User

Clang ++ optimized return code

Clang ++ automatically optimizes the code returned by the function, whether it is the c ++ 11 standard or the previous standard. The following is an example:

Note that clang ++ 3.5 does not use c ++ 11 by default.

 

 c++ --versionUbuntu clang version 3.5.0-4ubuntu2 (tags/RELEASE_350/final) (based on LLVM 3.5.0)Target: x86_64-pc-linux-gnuThread model: posix

Whether it is C ++ 11 or not, the output address of the following code is the same:

 

 

Class A {public: A () {cout <ctor <endl;} A (A const & src) {cout <copy <endl ;} A & operator = (A const & src) {cout <= <endl; return * this ;}; A test () {A; cout <& a <endl; return a;} int main (int argc, char ** argv) {try {A a2 = test (); cout <& a2 <
 
  

 

Output:

ctor0x7ffd4ed299980x7ffd4ed29998

 

An interesting phenomenon in the test function is that when the c ++ 11 Compilation option is not enabled, clang ++ Compiler's automatic optimization technology is used here. After the c ++ 11 option is enabled, the Code does not change, but the move semantics is used.

 

When this is the case, I returned a vector in a program a few days ago. , Encountered core dump, replaced with vector The & output parameter method is solved. We also need to further track whether it is a clang ++ 3.5 bug.

 

The following is a discussion post on stackoverflow, which is more valuable:

 

246 down vote accepted First example
std::vector
        
          return_vector(void){    std::vector
         
           tmp {1,2,3,4,5};    return tmp;}std::vector
          
            &&rval_ref = return_vector();
          
         
        

The first example returns a temporary which is caughtrval_ref. That temporary will have its life extended beyondrval_refDefinition and you can use it as if you had caught it by value. This is very similar to the following:

const std::vector
        
         & rval_ref = return_vector();
        

Could t that in my rewrite you obviusly can't use rval_ref in a non-const manner.

Second example
std::vector
        
         && return_vector(void){    std::vector
         
           tmp {1,2,3,4,5};    return std::move(tmp);}std::vector
          
            &&rval_ref = return_vector();
          
         
        

In the second example you have created a run time error. rval_ref now holds a reference to the destructed tmp inside the function. With any luck, this code wowould immediately crash.

Third example
std::vector
        
          return_vector(void){    std::vector
         
           tmp {1,2,3,4,5};    return std::move(tmp);}std::vector
          
            &&rval_ref = return_vector();
          
         
        

Your third example is roughly equivalent to your first. The std: move on tmp is unnecessary and can actually be a performance pessimization as it will inhibit return value optimization.

The best way to code what you're doing is:

Best practice
std::vector
        
          return_vector(void){    std::vector
         
           tmp {1,2,3,4,5};    return tmp;}std::vector
          
            rval_ref = return_vector();
          
         
        

I. e. just as you wocould in C ++ 03. tmp is implicitly treated as an rvalue in the return statement. it will either be returned via return-value-optimization (no copy, no move), or if the compiler decides it can not perform RVO, then it will use vector's move constructor to do the return. only if RVO is not saved med, and if the returned type did not have a move constructor wocould the copy constructor be used for the return.

Shareeditflag Answered Feb 13 '11 at 20:52 Howard Hinnant
74.1k12145133
 
6  
   
Great thanks for the elaborated answer! -Tarantula Feb 14' 11
10  
   
Compilers will RVO when you return a local object by value, and the type of the local and the return of the function are the same, and neither is cv-qualified (don't return const types ). stay away from returning with the condition (:?) Statement as it can inhibit RVO. Don't wrap the local in some other function that returns a reference to the local. Justreturn my_local;. Multiple return statements are OK and will not inhibit RVO.-Howard Hinnant Feb 25 '13
3  
   
There is a caveat: when returningMemberOf a local object, the move must be explicit.-boycy Feb 26 '13
4  
   
@ NoSenseEtAl: There is no temporary created on the return line.moveDoesn't create a temporary. it casts an lvalue to an xvalue, making no copies, creating nothing, destroying nothing. that example is the exact same situation as if you returned by lvalue-reference and removedmoveFrom the return line: Either way you 've got a dangling reference to a local variable inside the function and which has been destructed.-Howard Hinnant Feb 27 '13 at 11
1 Upvote
  Flag
Just a nit: Since youNamedThe variable (tmp) In the Best practice section, it is the NRVO that kicks in, not the RVO. These are two different optimizations. Other than that, great answer! -Daniel Frey Feb

 

Related Article

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.