Help | Site Map
Connecting Tech Pros Worldwide
 
 
LinkBack Thread Tools
  #1  
Old April 21st, 2007, 08:55 PM
MathWizard
Guest
 
Posts: n/a
Default Return object question

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
  #2  
Old April 22nd, 2007, 03:25 AM
David Harmon
Guest
 
Posts: n/a
Default Re: Return object question

On Sat, 21 Apr 2007 21:53:12 +0200 in comp.lang.c++, MathWizard
<no_mail@please.comwrote,
Quote:
>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.

  #3  
Old April 22nd, 2007, 10:15 AM
James Kanze
Guest
 
Posts: n/a
Default Re: Return object question

On Apr 21, 9:53 pm, MathWizard <no_m...@please.comwrote:
Quote:
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:
Quote:
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.
Quote:
Suppose I have also a class B and a constructor for A from B:
>
A::A(const B& b);
Quote:
The question is now about the following code:
Quote:
A what()
{
B my_B;
// do something with B.
return B;
}
Quote:
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.
Quote:
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: james.kanze@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

  #4  
Old April 23rd, 2007, 09:05 AM
Jeroen
Guest
 
Posts: n/a
Default Re: Return object question

James Kanze schreef:
Quote:
On Apr 21, 9:53 pm, MathWizard <no_m...@please.comwrote:
Quote:
>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:
>
Quote:
>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.
>
Quote:
>Suppose I have also a class B and a constructor for A from B:
>>
> A::A(const B& b);
>
Quote:
>The question is now about the following code:
>
Quote:
>A what()
>{
> B my_B;
> // do something with B.
> return B;
>}
>
Quote:
>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.
>
Quote:
>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: james.kanze@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
 

Bookmarks

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are Off
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On

What is Bytes?

We are a network of experts and professionals in IT and software development that help one another with answers to tough questions and share insights. Get the best answers to your questions from over network members.
Post your question now . . .
It's fast and it's free

Popular Articles