Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!convex!uunet!microsoft!jimad From: jimad@microsoft.UUCP (Jim ADCOCK) Newsgroups: comp.lang.c++ Subject: Re: GC, TC++ 1.01 calls X::X(X& (*this))! Keywords: GC, garbage collection, TC++, c++, copy constructors Message-ID: <70714@microsoft.UUCP> Date: 15 Feb 91 19:49:31 GMT References: <6309@celery34.UUCP> <70273@microsoft.UUCP> <6432@celery34.UUCP> Reply-To: jimad@microsoft.UUCP (Jim ADCOCK) Distribution: comp Organization: Microsoft Corp., Redmond WA Lines: 66 In article <6432@celery34.UUCP> stephens@motcid.UUCP (Kurt Stephens) writes: |jimad@microsoft.UUCP (Jim ADCOCK) writes: | |>I've been looking for the "correct" answer to these kinds of question |>on comp.std.c++ too. The questions being basically, what kinds of |>copies are allowed and/or not allowed, including in what situations |>is a compiler allowed to make a copy at the same address as a previous |>object, and do functions return by copy. | |To copy construct onto this'self doesn't make any sence at all. |It should not be allowed. A copy constructor should be *constructing* |a NEW object. Let me give you a couple counter-examples: A not uncommon C++ programming hack is to allocate a large block of memory, and use the placement operator to create an "Object" block header at the start of that block. The block header is used to keep information about the memory allocation. Then, if one creates subclasses of the block header, the placement operator is used again to create the new subclass header "on top of" the existing header. Admittedly, such an approach is a hack, but are you saying that compilers are allowed to generate copy constructors in such a way that re-constructing an object on top of its self will fail? -- If compilers *are* allowed to assume no aliasing problems between source and the copied object, then better, faster constructor code can be generated -- but then the placement hack won't necessarily work. Another variation on the placement hack is using placement and constructors such as to "change the type" of an object in place. Are constructors required to "work correctly" in those situations or not? Here's another example: A function "copy" has a const foo& for a parameter, and returns a foo by value. The compiler is smart enough to return the foo value in caller space, avoiding a temporary. The compiler is also smart enough to determine the foo being passed by reference never has its fields accessed after the call to copy, and it has no destructor side-effects to worry about. Can the compiler return the foo "value" in the same physical location as the the foo being passed as a reference? Why or why not? Note that the foo being passed as a parameter is "dead" after "copy", but the program might still make use of its address -- as long as that address is not dereferenced. Consider something like: #ifdef ONE_WAY_OR_ANOTHER inline #endif const foo copy(foo& parm) { return parm; } BOOL doesItCopy() { foo parm; const foo& return = copy(parm); if (&parm == &return) return NO; else return YES; } Must the "copy" of the value returned be in a separate place, or can the copy be returned in the same place? -- Again, this is an important issue for people doing "object-oriented" programming, using addresses to represent "identity." And if the copy constructor is simply bit-wise copy, and "copy" is inline, one can easily imagine where optimizing compilers would love to place parm and return at the same location -- then the whole "copy" routine becomes a NO-OP!