Jump to content
  • Advertisement

Archived

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

grady

can I return by reference to prevent creating temporary value

This topic is 5810 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
Advertisement
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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!