Archived

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

NRV Program Transformation - Where is it!?

This topic is 5148 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

In Stephen Dewhurt''s C++ Gotchas, pg. 158, Ignorance of Return Value Optimizations, Stephen forwards the notion that compilers will optimize out functions that return a class object so that no temporary object is constructed to initialize the variable on the left hand side of the statement. object = GetObject(); I.E., I believe he claims that when in release, the code will implicitly pass in the object variable by reference so that it gets written directly. I rejoiced at this notion. I thought, wow I''m gonna stop caring about writing these horrible awkward functions which take in a pointer/reference as a return value (as long as my functions were simple like Dewhurst indicates). Naturally co-workers were like "what are you doing"? I told them, and they didn''t believe. And then I ran a test in a release build with logs in copy constructors and regular constructors, and low and behold no optimization were in place. I am using Visual Studio .NET 2003 with most of the optimizations turned on, especially more speed for more size. I would give my left leg to any programmer or programmers who can lead me down the right path to finding these program transformations. My appreciation is genuine - thanks a lot.

Share this post


Link to post
Share on other sites
The problem might be that since the object can (and does) have an operator =, the compiler can't get rid of the temporary. Its like calling object.somefunctions(GetObject()); . The function can do anything, and the compiler can't be sure that all it does is make a shallow copy.
In other words, '=' doesn't have to mean the assignment operator when dealing with classes, because it could be defined to add two classes together, deltree c:\, or anything you can do in the language.
maybe.

[edited by - extrarius on November 8, 2003 2:50:20 AM]

Share this post


Link to post
Share on other sites
Putting logging in the copy contructor and operator=() will disable RVO because the functions will contain side effects. As far as I know, Visual Studio .NET 2003 will do both ARVO and NRVO, but the only way to verify it would be to look at the actual assembly output. And here''s the real kicker, it only works reliably if the functions are inlined, so there''s no real way to tell what benefit is from RVO and what''s a traditional inline gain.

Bulka and Mayhew''s "Efficient C++", ISBN 0-201-37950-3, contains a chapter dedicated to situations that may be ARVO''d or NRVO''d.

Also, I don''t think MSVC 7.1 will perform RVO if copy construction or assignment can throw.

Share this post


Link to post
Share on other sites
Thanks so much for the analysis. Is it your opinion then, that I should not even define the copy constructor and operator=. Will defining them always throw off the compiler? Or is the compiler smart enough to differentiate between what''s extra and what''s not?

I''ll certainly try and dig throug the assembly when I get a chance.

Thanks so much.

Share this post


Link to post
Share on other sites