Archived

This topic is now archived and is closed to further replies.

can I return by reference to prevent creating temporary value

This topic is 5504 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I have a class that has some member functions. say for a matrix I have an transpose function that can be used like so: double filldata[] ={ 1, 2, 3,4, 5,6,7,8,9}; mat3 M( filldata ); M.trn( ); this code makes M the transpose of the matrix formed by the filldata. But suppose I want to write the function such that it returns a value, so that I can do things like: double filldata[] ={ 1, 2, 3,4, 5,6,7,8,9}; mat3 A; mat3 M( filldata ); A = M.trn( ); If I define the trn() function like so: mat3 &trn() { //do a transpose on the matrix; return *this; } since I return by reference will that prevent a temporary object from being created when the trn function returns? I know I could define functions that take pointers for arguments and let all my functions return pointers like D3DX math functions so that the return value of a function can be used as an argument to another funcion, but I don''t want people using this library to deal with pointers if they don''t have to; and I''m writing this lib all in C++ so if its possible to avoid, I definently don''t want to do it. thaks in advance for any advice.

Share this post


Link to post
Share on other sites
quote:
Original post by grady
since I return by reference will that prevent a temporary object from being created when the trn function returns?
Yes. What you''re doing works fine. But I would never call a function named "trn"

Share this post


Link to post
Share on other sites
As far as I know, this would only work if you returned *this. In other cases where you construct a value and then return it, you cannot return a &.
However as far as I know GCC and VC (probably, I''m not sure) do Named Return Value Optimization (NRVO). I''m sure GCC does it. Basically if you do something like:

matrix matrix::dosomething() {
matrix m(...);
return m;
}

in quite a lot of cases, the compiler can optimize away the temporary. I''m pretty sure VC does this since VC is ..a very good optimizing compiler.


-----------------------------
Gamedev for learning.
libGDN for putting it all together.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
quote:

However as far as I know GCC and VC (probably, I''m not sure) do Named Return Value Optimization (NRVO). I''m sure GCC does it.



gcc3.1 does this for sure, gcc3.0 may. Anyways, from what I understand NRVO just allocates the return variable in the return register, such as eax for x86 asm. I don''t see how this works with values larger than 32-bits though. Anyone are to explain?

Share this post


Link to post
Share on other sites
The RVO is more complicated than that.


#include <iostream>
using namespace std;

struct T
{
T () { cout << "D"; } // default construction
T (T const&) { cout << "C"; } // copy construction
};
T f1 () { return T(); }
T f2 () { T t; return t; }
T f3 () { T t; t = T(); return t; }
int main ()
{
cout << "min D max D = ";
T t1;
cout << endl;
cout << "min D max DC = ";
#ifndef __GNUC__
T t2( (T()) ); // to avoid most vexing parse
#else // __GNUC__
T t2((0, T())); // to avoid g++ parse bug
#endif // __GNUC__
cout << endl;
cout << "min D max DC = ";
T t3 = T();
cout << endl;
cout << "min D max DCC = ";
T t4(f1());
cout << endl;
cout << "min D max DCC = ";
T t5 = f1();
cout << endl;
cout << "min D max DCC = ";
T t6(f2());
cout << endl;
cout << "min D max DCC = ";
T t7 = f2();
cout << endl;
cout << "min DD max DDCC = ";
T t8(f3());
cout << endl;
cout << "min DD max DDCC = ";
T t9 = f3();
cout << endl;
}


g++ will eliminate every single copy construction. I think Intel will too, not sure. VC++ leaves some in.

About the parse bug: To avoid the most vexing parse ((C) Scott Meyers), one should wrap the constructor call in brackets, to force it to be treated as an expression rather than a function pointer declaration. However, g++ has a parse bug, and will halt the compile. The insertion of the "0," forces evaluation as an expression -- thereby fixes the most vexing parse -- but prevents VC++ from performing the RVO properly.

From http://groups.google.com/groups?hl=en&lr=&ie=UTF-8&oe=UTF-8&safe=off&frame=right&th=a0bc5c8ff07e8a0f&seekm=9fn050%246n4%241%40taliesin.netcom.net.uk#link5


[edited by - DrPizza on November 20, 2002 4:45:10 AM]

Share this post


Link to post
Share on other sites