NICE-ESG-Libs Digest Thu, 20 Apr 95 Volume 1 : Issue 211
Today's Topics:
fwd: [jacob@blackbox.enmu.edu] Re: Copy/setup/consistent
NICE Eiffel Standards Group -- Library Committee Mailing List
To post to list:
NICE-ESG-Libs@atlanta.twr.com
To send mail to the Chairman of the committee:
NICE-ESG-Libs-chair@atlanta.twr.com
Administrative matters (sign up, unsubscribe, mail problems, etc):
NICE-ESG-Libs-request@atlanta.twr.com
Date: Thu, 20 Apr 95 08:00:28 EDT
From: tynor (Steve Tynor)
Subject: fwd: [jacob@blackbox.enmu.edu] Re: Copy/setup/consistent
To: nice-esg-libs
Library Committee members,
In cleaning up a backlog of email, I discovered this mail from Jacob
Gore which I'd promised to forward to the library committee. My
apologies to Jacob for the delay.
Steve
------- start of forwarded message (RFC 934 encapsulation) -------
From: "Jacob Gore"
Subject: Re: Copy/setup/consistent
Steve,
I picked up PELKS-7. While I am happy with the removal of `setup' and
`consistent', I don't think that the problem I have with `clone' has been
addressed. In fact, I don't see how `clone' could be useful unless its
algorithm is spelled out in the standard. Since it is frozen, it should
have a standard algorithm, right? By the way, if there is a frozen
`standard_clone', is it really necessary to freeze `clone'? If they are
both frozen, why do they have different description comments -- are they
not synonyms forever?
There is no explanation of "the default copying semantics," but two
algorithms come to mind:
1. "Just allocate space and call `copy'":
clone(other: GENERAL): like other is
do
!!Result;
Result.copy(other);
end;
2. "Allocate space, do bitwise copy, and call `copy'":
clone(other: GENERAL): like other is
do
Result := C_function_to_malloc_and_bcopy(other);
Result.copy(other);
end;
The problem with Alg. 1 is that "!!Result" does not ensure the class
invariant (since it does not call a creation routine), so
"Result.copy(other)" may crash.
The current Tower implementation, if I understand it correctly, does Alg.
2. Since `other' obeys the invariant, so will a bitwise copy of `other'.
However, if `other' has features that reference other objects, same
features in `Current' will end up referencing the same objects. If
`copy(other)' is immediately called, this aliasing can destroy the
internals of `other' -- and that is exactly what happens in many of the
object structure examples in my book.
An easy way to deal with the problem is to start the redefined
(object-structure-specific) `copy' like this:
copy(other: like Current) is
do
-- In case this routine was called from `clone',
-- disentangle the entities of `Current' from
-- the objects referenced from within `other'.
make;
-- proceed with the actual copying
Is this the prescribed way do deal with the problem? It sure looks like a
kluge... And it may be quite inefficient when `copy' is NOT called from
`clone', since then the reinitialization is wasted. If you do this, you
may as well ditch `copy', and let programmers redefine `clone' and always
do "x := clone(y)" instead of "x.copy(y)".
Jacob
------- end -------
