Returning local memory as reference from function

Pages: 12
Thanks.

I found that conditions for NRVO are met with the statement is to use the following:
 
Matrix M3 = M1 + M2;


instead if I use
1
2
Matrix M3;
M3 = M1 + M2;


Then:

op+ called
ctor called
operator= called
dtor Called  ///now both =operator and dtor are called -- which we want to avoid
3

In other words for the condition that the compiler needs to perform NRVO is to use statements like Matrix M3=M1 + M2 - I believe Cubbi was trying to tell this much before. This is very useful indeed , precisely what I need!
Last edited on
NRVO happened in your assignment expression as well: the matrix object that operator+ constructs and fills in, becomes exactly the argument that operator= gets by value. The copy ctor is elided.
Cubbi - I think I understand what you are saying. NRVO and copy elision are related terms which I am trying to understand bit more . I interprete your last statement "The copy ctor is elided" as the copy ctor is "excluded" from the operator= execution during non-return value optimization. Is this correct?
Yes, copying just doesn't happen. (it's "named return value", the object that op+ returns has a name within that operator)
Note that an assignment operator that copies data manually instead of relying on pass by value and swap, cannot be optimized this way.
Sorry for overloading this thread but I have another question. If I want to create multiple objects from a single function and return them, I could think of no way other than passing pointers to that function. such as

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/// this is a member function of class matrix discussed previously
/// I have a situation where both the matrices need to be built simultaneously from a single matrix 
void returnMultipleMatrices( matrix* &m1, matrix* &m2 )
         {
                 std::cout << "returnMultipleMatrices called\n";
                 m1 = new matrix (cols, rows);
                 m2 = new matrix (cols, rows);
                 for( int i = 0; i < rows; ++i )
                 {
                         for( int j = 0; j < cols; ++j )
                         {
                                 m1->mat[j][i] =  mat[i][j];
                                 m2->mat[j][i] = mat[i][j] + 5.0;
                         }
                 }
         }


Then from main I call this function
1
2
3
4
5
6
7
        matrix *M_t1=0, *M_t2=0;
        M2.returnMultipleMatrices( M_t1, M_t2 );
        std::cout << M_t1->element(500,500) << "\n";
        std::cout << M_t2->element(500,500) << "\n";

        delete M_t1;
        delete M_t2;


The above works fine, but from previous discussion it seemed that returning pointers that needed to be deleted later is not desirable.

Thank you
Please ignore by above post. Multiple matrices can indeed be passed as references and returned without any problems: eg:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//return a submatrix from [0..n1,0..n2]
         matrix submatrix( int n1, int n2 )
         {
                 std::cout << "submatrix Called\n";
                 if( n1 >= rows && n2 >= cols )
                 {
                         std::cout << "ERROR : bounds of submatrix violated\n";
                         assert(0);
                 }
                 matrix m (n1, n2 );
                 for( int i = 0; i < n1; ++i )
                         for( int j = 0; j < n2; ++j )
                                 m.mat[i][j] = mat[i][j];
                 return m;
         }

         //return submatrix of 2 different sizes
         void returnSubmatrices( matrix &m1, matrix &m2, const int size1, const int size2 )
         {
                 std::cout << "returnSubmatrices called\n";
                 //create a copy of *this matrix
                 matrix cpMat = ( *this );
                 m1 = cpMat.submatrix((int)rows/size1, (int)cols/size1);
                 m2 = cpMat.submatrix((int)rows/size2, (int)cols/size2);
         }


returnSubmatrices was called from main and the test passed without any problems:
1
2
3
4
5
 
       matrix Msub1, Msub2;
        M4.returnSubmatrices( Msub1, Msub2, 2, 5 );
        std::cout << Msub1.element(10,10) << "\n";
        std::cout << Msub2.element(10,10) << "\n";

"pass-by-value and swap" worked fine for this test. Only that operator= will be invoked.
Topic archived. No new replies allowed.
Pages: 12