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

Is a copy constructor needed for the return value optimization?

P: n/a
SzH

The code below demonstrates that the copy constructor of moo is not
called on the first line of main. In spite of this, g++ (version 4.1.2)
refuses to compile it if I make the copy constructor private. But the
Digital Mars compiler does not complain.

Which compiler is right? (And if gcc is right, why does this restriction
exist?)

Szabolcs

#include <iostream>

struct moo {
int data;

moo(int n) : data(n) {
std::cout << "constructor\n";
}

// private:
moo(const moo &m) : data(m.data) {
std::cout << "copy constructor\n";
}
};

moo fun() {
return moo(3);
}

int main() {
moo m = fun();
return 0;
}
Apr 25 '07 #1
Share this Question
Share on Google+
10 Replies


P: n/a
SzH wrote:
>
The code below demonstrates that the copy constructor of moo is not
called on the first line of main. In spite of this, g++ (version 4.1.2)
refuses to compile it if I make the copy constructor private. But the
Digital Mars compiler does not complain.

Which compiler is right? (And if gcc is right, why does this restriction
exist?)
Return value optimization, as the name says, is an optimization.
Optimizations should never make incorrect code compile, nor make valid
code fail to compile. Returning a result by value, as your function
does, requires copying the value, which in turn requires an accessible
copy constructor. When you make the copy constructor inaccessible you
cannot return an object of that type by value.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Apr 25 '07 #2

P: n/a
SzH
Pete Becker wrote:
SzH wrote:
>>
The code below demonstrates that the copy constructor of moo is not
called on the first line of main. In spite of this, g++ (version
4.1.2) refuses to compile it if I make the copy constructor private.
But the Digital Mars compiler does not complain.

Which compiler is right? (And if gcc is right, why does this
restriction exist?)

Return value optimization, as the name says, is an optimization.
Optimizations should never make incorrect code compile, nor make valid
code fail to compile. Returning a result by value, as your function
does, requires copying the value, which in turn requires an accessible
copy constructor. When you make the copy constructor inaccessible you
cannot return an object of that type by value.
I can not agree with this completely. If it was just a "normal"
optimisation then the result of the program should not depend on whether
the optimisation is performed or not. When I run the program, the line
"copy constructor" is not printed, so I can tell that the optimisation
was performed (i.e. the value was not copied).
Apr 25 '07 #3

P: n/a
SzH wrote:
Pete Becker wrote:
>SzH wrote:
>>>
The code below demonstrates that the copy constructor of moo is not
called on the first line of main. In spite of this, g++ (version
4.1.2) refuses to compile it if I make the copy constructor private.
But the Digital Mars compiler does not complain.

Which compiler is right? (And if gcc is right, why does this
restriction exist?)

Return value optimization, as the name says, is an optimization.
Optimizations should never make incorrect code compile, nor make
valid code fail to compile. Returning a result by value, as your
function does, requires copying the value, which in turn requires an
accessible copy constructor. When you make the copy constructor
inaccessible you cannot return an object of that type by value.

I can not agree with this completely. If it was just a "normal"
optimisation then the result of the program should not depend on
whether the optimisation is performed or not.
The Standard explicitly allows this kind of optimization regardless
of the presence of side effects in the constructor. BTW, RVO is just
about the only optimization the Standard actually defines. And it
has to do that explicitly to state the "regardless of side effects"
portion.
When I run the program,
the line "copy constructor" is not printed, so I can tell that the
optimisation was performed (i.e. the value was not copied).
So? It doesn't remove the requirement that the Standard sets forth.
The code is ill-formed _if_ the copy *cannot* be made should it be
necessary to make it.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 25 '07 #4

P: n/a
SzH
Victor Bazarov wrote:
The Standard explicitly allows this kind of optimization regardless
of the presence of side effects in the constructor. BTW, RVO is just
about the only optimization the Standard actually defines. And it
has to do that explicitly to state the "regardless of side effects"
portion.
Just to make sure that I understand this correctly:
So the Standard *allows* this optimisation, but it does not *require*
it. Is this right?

Could you please point me to the relevant section of the Standard?
Unfortunately I was unable to find it myself.
Apr 25 '07 #5

P: n/a
SzH wrote:
Pete Becker wrote:
>SzH wrote:
>>>
The code below demonstrates that the copy constructor of moo is not
called on the first line of main. In spite of this, g++ (version
4.1.2) refuses to compile it if I make the copy constructor private.
But the Digital Mars compiler does not complain.

Which compiler is right? (And if gcc is right, why does this
restriction exist?)

Return value optimization, as the name says, is an optimization.
Optimizations should never make incorrect code compile, nor make valid
code fail to compile. Returning a result by value, as your function
does, requires copying the value, which in turn requires an accessible
copy constructor. When you make the copy constructor inaccessible you
cannot return an object of that type by value.

I can not agree with this completely. If it was just a "normal"
optimisation then the result of the program should not depend on whether
the optimisation is performed or not. When I run the program, the line
"copy constructor" is not printed, so I can tell that the optimisation
was performed (i.e. the value was not copied).
That's a different issue: the compiler is allowed to skip the copy
constructor. That doesn't make the code without an accessible copy
constructor valid, though. As I said, the optimization doesn't turn
invalid code into valid code.

--

-- Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com)
Author of "The Standard C++ Library Extensions: a Tutorial and
Reference." (www.petebecker.com/tr1book)
Apr 25 '07 #6

P: n/a
SzH wrote:
Victor Bazarov wrote:
>The Standard explicitly allows this kind of optimization regardless
of the presence of side effects in the constructor. BTW, RVO is just
about the only optimization the Standard actually defines. And it
has to do that explicitly to state the "regardless of side effects"
portion.

Just to make sure that I understand this correctly:
So the Standard *allows* this optimisation, but it does not *require*
it. Is this right?
Yes.
Could you please point me to the relevant section of the Standard?
Unfortunately I was unable to find it myself.
12.8/15

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 25 '07 #7

P: n/a
On Wed, 25 Apr 2007 14:39:07 -0400, "Victor Bazarov" wrote:
>SzH wrote:
>I can not agree with this completely. If it was just a "normal"
optimisation then the result of the program should not depend on
whether the optimisation is performed or not.

The Standard explicitly allows this kind of optimization regardless
of the presence of side effects in the constructor.
This should be regarded as bug in the C++ Standard.
--
Roland Pibinger
"The best software is simple, elegant, and full of drama" - Grady Booch
Apr 25 '07 #8

P: n/a
Roland Pibinger wrote:
On Wed, 25 Apr 2007 14:39:07 -0400, "Victor Bazarov" wrote:
>SzH wrote:
>>I can not agree with this completely. If it was just a "normal"
optimisation then the result of the program should not depend on
whether the optimisation is performed or not.

The Standard explicitly allows this kind of optimization regardless
of the presence of side effects in the constructor.

This should be regarded as bug in the C++ Standard.
I don't see any defect report on it. Have you submitted one?

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Apr 25 '07 #9

P: n/a
On Apr 25, 8:28 pm, SzH <szhorvat-nospample...@gmail.comwrote:
Pete Becker wrote:
SzH wrote:
The code below demonstrates that the copy constructor of moo is not
called on the first line of main. In spite of this, g++ (version
4.1.2) refuses to compile it if I make the copy constructor private.
But the Digital Mars compiler does not complain.
Which compiler is right? (And if gcc is right, why does this
restriction exist?)
Return value optimization, as the name says, is an optimization.
Optimizations should never make incorrect code compile, nor make valid
code fail to compile. Returning a result by value, as your function
does, requires copying the value, which in turn requires an accessible
copy constructor. When you make the copy constructor inaccessible you
cannot return an object of that type by value.
I can not agree with this completely. If it was just a "normal"
optimisation then the result of the program should not depend on whether
the optimisation is performed or not.
Right. It's not normal optimization; it's a special hack. On
the other hand, it does seem reasonable to expect copy
constructors to copy.
When I run the program, the line "copy constructor" is not
printed, so I can tell that the optimisation was performed
(i.e. the value was not copied).
Correct. The standard explicitly allows this.

It doesn't change the fact that conceptually, a copy was
required; the standard just allows the compiler to ignore
observable behavior that occurs in the copy constructor and the
destructor. For purposes of optimization.

--
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 26 '07 #10

P: n/a
On Apr 25, 10:45 pm, rpbg...@yahoo.com (Roland Pibinger) wrote:
On Wed, 25 Apr 2007 14:39:07 -0400, "Victor Bazarov" wrote:
SzH wrote:
I can not agree with this completely. If it was just a "normal"
optimisation then the result of the program should not depend on
whether the optimisation is performed or not.
The Standard explicitly allows this kind of optimization regardless
of the presence of side effects in the constructor.
This should be regarded as bug in the C++ Standard.
Sort of. It's a hack. It was felt that it wouldn't make a
difference in well written C++ code (which is certainly true),
and that the optimization was too important to take support for
poorly written C++ into account. It's certain, however, that it
places games with the C++ object model.

--
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 26 '07 #11

This discussion thread is closed

Replies have been disabled for this discussion.