On Tue, 30 Aug 2005 10:09:40 GMT,
al***@start.no (Alf P. Steinbach) wrote:
"This change was necessary to avoid the problems that can come up when
compilers are permitted to wantonly elide copy construction, especially
when copy construction has side effects. There are cases where
reasonable code may rely on the number of copies actually made of an
object."
I'm not very clear about this reason
Neither am I. ;-)
It would have been nice if the relevant paragraphs in the standard were
referred to.
Some people had code examples where they cared about the presence or
absence of side effects (I think one example was logging).
What kind of side-effects of copy construction can lead to problems.
All kinds, so the question is rather what kind of side-effect of copy
construction does _not_ lead to problems, i.e. can be relied on.
Any side effect that the programmer cares about can lead to problems if
the compiler removes it. Of course, knowing which ones those are requires
reading the programmer's mind. :-) For example, if the side effect is to
increment a global counter keeping track of how many times a certain thing
happened, then in some cases you don't care if it's not updated, but in
some cases you do care (e.g., if you're relying on the count for
instrumenting how many times a code path was taken).
The bottom line is that copy constructor elision changes the meaning of
the program, although in a way that's innocuous for all plain value types
(which many C++ types are) and for many more complex types. But whenever
you change the sequence of actions that the programmer wrote, you run the
risk that you might not be doing him a favor.
An example would help me understand
this better. Also, if code relies on the actual number of copies made
of an object, would it not be affected by return value optimization?
One would think so.
Yes, it would. But when the committee in 1997 restricted the freedom for
the compiler to elide copies, the RVO was explicitly and specially
excluded so that compilers could continue to elide copies of return
values. True, giving one case special treatment wasn't consistent, but
people weren't willing to give up the RVO largely because the RVO was
known to have important performance benefits in some scenarios, and the
scope for surprising programmers by eliding copies of return values in
particular seemed to be less.
Note that probably all of this could have been regularized if the language
had had move constructors, which presumably could be applied to RVO-style
cases. Howard Hinnant is now proposing move construction/assignment for
C++0x and so far is getting a warm reception by the committee. Google for
"wg21 hinnant move constructor" for more details on this interesting
topic.
Herb
---
Herb Sutter (
www.gotw.ca) (
www.pluralsight.com/blogs/hsutter)
Convener, ISO WG21 (C++ standards committee) (
www.gotw.ca/iso)
Contributing editor, C/C++ Users Journal (
www.gotw.ca/cuj)
Architect, Developer Division, Microsoft (
www.gotw.ca/microsoft)