By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,939 Members | 1,541 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,939 IT Pros & Developers. It's quick & easy.

Return object question

P: n/a
Hi,

I have a question about returning an object in a function and calling a
copy constructor. As far as I understand, in the following code the copy
constructor may or may not be called, depending on the compiler:

A what()
{
A my_A;
// do something with A.
return A;
}

Suppose I have also a class B and a constructor for A from B:

A::A(const B& b);

The question is now about the following code:

A what()
{
B my_B;
// do something with B.
return B;
}

As far as I can see, the constructor 'A::A(const B& b)' must be called
in order to return an object A. But is it possible that after that
constructor some (stupid) compiler decides that the copy constructor for
A must be called also? Maybe some compiler might think that the copy
constructor must be called always if an object must be returned...

Thansk for any answers,

Jeroen
Apr 21 '07 #1
Share this Question
Share on Google+
3 Replies


P: n/a
On Sat, 21 Apr 2007 21:53:12 +0200 in comp.lang.c++, MathWizard
<no*****@please.comwrote,
>As far as I can see, the constructor 'A::A(const B& b)' must be called
in order to return an object A. But is it possible that after that
constructor some (stupid) compiler decides that the copy constructor for
A must be called also?
Yes, it is completely expected if your compiler is a little bit simple.
A compiler smart enough to skip it is doing "return value optimization".
The smart compiler is still required to check that the copy constructor
is accessible and give you an error if not, even though it's not called.

Apr 22 '07 #2

P: n/a
On Apr 21, 9:53 pm, MathWizard <no_m...@please.comwrote:
I have a question about returning an object in a function and calling a
copy constructor. As far as I understand, in the following code the copy
constructor may or may not be called, depending on the compiler:
A what()
{
A my_A;
// do something with A.
return A;
}
Correct. Technically, the semantics specified by the standard
require that the copy constructor be called, but the standard
then gives the compiler explicit authorization to merge my_A and
the return value, and not call the copy constructor. (Note that
while not calling the copy constructor is the most visible
effect, there are others as well.) This is called NRVO: Named
Return Value Optimization.
Suppose I have also a class B and a constructor for A from B:

A::A(const B& b);
The question is now about the following code:
A what()
{
B my_B;
// do something with B.
return B;
}
As far as I can see, the constructor 'A::A(const B& b)' must be called
in order to return an object A. But is it possible that after that
constructor some (stupid) compiler decides that the copy constructor for
A must be called also?
The formal semantics are almost the same as above: first you
construct a temporary of type A, then you copy it into the
return value. Again, the standard explicitly allows the
compiler to elide the copy.
Maybe some compiler might think that the copy
constructor must be called always if an object must be returned...
The copy constructor must be callable in both cases, or the code
is illegal. But I think that most compilers today elide the
copy in both cases.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Apr 22 '07 #3

P: n/a
James Kanze schreef:
On Apr 21, 9:53 pm, MathWizard <no_m...@please.comwrote:
>I have a question about returning an object in a function and calling a
copy constructor. As far as I understand, in the following code the copy
constructor may or may not be called, depending on the compiler:
>A what()
{
A my_A;
// do something with A.
return A;
}

Correct. Technically, the semantics specified by the standard
require that the copy constructor be called, but the standard
then gives the compiler explicit authorization to merge my_A and
the return value, and not call the copy constructor. (Note that
while not calling the copy constructor is the most visible
effect, there are others as well.) This is called NRVO: Named
Return Value Optimization.
>Suppose I have also a class B and a constructor for A from B:

A::A(const B& b);
>The question is now about the following code:
>A what()
{
B my_B;
// do something with B.
return B;
}
>As far as I can see, the constructor 'A::A(const B& b)' must be called
in order to return an object A. But is it possible that after that
constructor some (stupid) compiler decides that the copy constructor for
A must be called also?

The formal semantics are almost the same as above: first you
construct a temporary of type A, then you copy it into the
return value. Again, the standard explicitly allows the
compiler to elide the copy.
>Maybe some compiler might think that the copy
constructor must be called always if an object must be returned...

The copy constructor must be callable in both cases, or the code
is illegal. But I think that most compilers today elide the
copy in both cases.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34
OK, thanks for the answer James. But it looks like I'm stuck with my
'solution'. The thing is, I have a function which was originally
implemented as:

A special_function()
{
A my_A;
// do something with A.
return A;
}

I call it 'special_function' here, because here, if the copy constructor
is called, the copy constructor must do something different than in all
other cases when the copy constructor for 'A' is called.

So I wanted to make a solution with:

A special_function()
{
B my_B;
// do something with B.
return B;
}

so that I could force to use the constructor from B to A and thus
implement the slightly different behaviour for returning from
'special_function'. But if the copy constructor for A is then called
afterwards, then things will crash again...

I also thought of setting a property in class A, like:

A special_function()
{
A my_A;
// do something with A.

// Prepare for special behaviour of the copy constructor.
A.in_special_function = true;

return A;
}

so that the copy constructor can test for that. But if NRVO is applied,
then the property remains set after A is returned and the special
behaviour of the copy constructor may be applied to the returned object
A somewhere in the code where I don't want it... For instance in the
situation:

void function2(A a)
{
}

function2(special_function());

Because the copy constructor is called when calling function2 while the
property 'A.in_special_function' may still be true at that time.

Any ideas maybe? Or is the description of my problem too vague :-)

Jeroen
Apr 23 '07 #4

This discussion thread is closed

Replies have been disabled for this discussion.