Path: utzoo!utgpu!utstat!jarvis.csri.toronto.edu!mailrus!tut.cis.ohio-state.edu!ucbvax!ulysses!hector!jss From: jss@hector.UUCP (Jerry Schwarz) Newsgroups: comp.lang.c++ Subject: Re: C++ constructor and function semantics Message-ID: <11310@ulysses.homer.nj.att.com> Date: 13 Mar 89 19:03:51 GMT References: <1105@oswego.Oswego.EDU> Sender: netnews@ulysses.homer.nj.att.com Reply-To: jss@hector.UUCP (Jerry Schwarz) Organization: AT&T Bell Laboratories Lines: 59 In article <1105@oswego.Oswego.EDU> dl@rocky.oswego.edu (Doug Lea) writes: > >My best explanation for the difference between `X var(fun())' and >`X var = fun()' is that it represents an implementation >error. ... > >Of course, the interesting question is, which behavior is `correct'? >That is, should `X var(fun())' behave like the current `X var = fun()' >or vice versa? Other points of interest in these examples will turn >out to also rest on this issue. The answer here is (and should be) that either behavior is correct. What is happening is that in one case the compiler has decided to put the return value into a temporary before constructing "var" from that temporary and in the other case it has decided not to. One difference between X(X&) and ordinary functions is that C++ may call X(X&) when it constructs temporaries and that the number of temporaries (of type X) that are required to evaluate any particular statement is undefined. When writing X(X&) the programmer must be aware of the possibility that it may be used to construct temporaries and take that into account. Doug has inverted the possible "optimizations". In no case may a compiler elide an explicit call to a constructor, but it may insert calls that are not explicitly there. "Optimization" consists in inserting as few extra calls as possible. By the way, if X::~X() (the destructor) is declared it must eventually be called on any temporaries. >First, a bit of motivation about why someone might desire volatile >X(X&) constructors: There now exist a collection of C++ programming >`tricks' devised by just about everyone who implements `value >oriented' classes (to use Jerry Schwarz's apt term) in order to avoid >the `useless' copies of data held by objects in various calculations >that would otherwise be forced via X(X&) constructors. ... > >The validity of this kind of bookkeeping information is often very >dependent on knowledge of the precise constructor sequences encountered >across declarations, by-value function calls, and by-value function >returns. > The "tricks" are akin to reference counting. (There is more to it, but this is not the place to discuss details.) Because C++ guarantees that a constructor will be called for any space it uses as an X (e.g. the space used for function arguments) it is possible to write such code so that it is correct whatever sequences are actually invoked. Although the efficiency of the resulting code may be lowered if the C++ compiler chooses to create a lot of temporaries. Jerry Schwarz AT&T Bell Labs, Murray Hill