467,168 Members | 968 Online
Bytes | Developer Community
Ask Question

Home New Posts Topics Members FAQ

Post your question to a community of 467,168 developers. It's quick & easy.

Please explain this unexpected behavior (regarding return-by-value)


Hi, I came across this unexpected behavior while working on something
else. I am attempting to return a custom type by value from a global
function. I have a trace in the custom class's copy constructor, and I
expected this code to tell me that the custom copy constructor had been
called twice. Instead, it's only called once and the program executes
correctly.

Is this an optimization related to my compiler (g++ v4.0.1) or is this
specified by the standard? Can somebody clear this behavior up for me?

Thanks in advance!

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// start example source
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;

class Test
{
string member_;

public:
Test(const string& s) : member_(s) { }
Test(const Test& copy) : member_(copy.member_) {
cout << "copy" << endl;
}

void out() { cout << member_ << endl; }

};

Test test_by_value(const Test& in)
{

Test temp(in); // expect a copy here while constructing temp
return temp; // also expect a copy here to return the value of
temp, which currently exists on the stack
}

int main()
{
Test t("hello");
Test v = test_by_value(t);
v.out();

return 0;
}
/*
expected output:
copy
copy
hello
actual output:
copy
hello

how is the copied value being returned from test_by_value() without a
second copy (since temp is a stack var)?
*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////

Nov 10 '06 #1
  • viewed: 1340
Share:
4 Replies
* du********@gmail.com:
Hi, I came across this unexpected behavior while working on something
else. I am attempting to return a custom type by value from a global
function. I have a trace in the custom class's copy constructor, and I
expected this code to tell me that the custom copy constructor had been
called twice. Instead, it's only called once and the program executes
correctly.
Copy constructor calls are allowed to be optimized away -- in many
situations -- regardless of possible side-effects in the copy constructor.

So generally you can't "expect" any specific number of calls.

For your specific example, look up RVO and NRVO.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Nov 10 '06 #2

du********@gmail.com wrote:
Hi, I came across this unexpected behavior while working on something
else. I am attempting to return a custom type by value from a global
function. I have a trace in the custom class's copy constructor, and I
expected this code to tell me that the custom copy constructor had been
called twice. Instead, it's only called once and the program executes
correctly.

Is this an optimization related to my compiler (g++ v4.0.1) or is this
specified by the standard? Can somebody clear this behavior up for me?

Thanks in advance!

//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// start example source
#include <string>
#include <iostream>
using std::string;
using std::cout;
using std::endl;

class Test
{
string member_;

public:
Test(const string& s) : member_(s) { }
Test(const Test& copy) : member_(copy.member_) {
cout << "copy" << endl;
}

void out() { cout << member_ << endl; }

};

Test test_by_value(const Test& in)
{

Test temp(in); // expect a copy here while constructing temp
return temp; // also expect a copy here to return the value of
temp, which currently exists on the stack
}

int main()
{
Test t("hello");
Test v = test_by_value(t);
v.out();

return 0;
}
/*
expected output:
copy
copy
hello
actual output:
copy
hello

how is the copied value being returned from test_by_value() without a
second copy (since temp is a stack var)?
*/

Because the following:

Test v = test_by_value(t);

is usually optimized to:

Test v(test_by_value(t));

which is completely legal, btw.

Note the same happens with a primitive:
int x(99);
int n = x; // is actually a copy

Nov 10 '06 #3

<du********@gmail.comwrote in message
news:11**********************@m73g2000cwd.googlegr oups.com...
Is this an optimization related to my compiler (g++ v4.0.1) or is this
specified by the standard? Can somebody clear this behavior up for me?
VS2005 does a similar optimization, the NRVO
(http://msdn.microsoft.com/library/de...rvo_cpp05.asp).

--
Marco
Nov 10 '06 #4
On 9 Nov 2006 20:58:52 -0800, du********@gmail.com wrote:
>Is this an optimization related to my compiler (g++ v4.0.1) or is this
specified by the standard? Can somebody clear this behavior up for me?
This 'optimization' (the (N)RVO hack) is compiler specific. IIRC, you
can turn it off with a compiler switch for g++.

Best wishes,
Roland Pibinger
Nov 10 '06 #5

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

17 posts views Thread by matthias_k | last post: by
4 posts views Thread by Generic Usenet Account | last post: by
12 posts views Thread by Sanjeev | last post: by
9 posts views Thread by Jeff Louie | last post: by
1 post views Thread by matko | last post: by
1 post views Thread by Kevin Walzer | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.