From: "Peter C. Chapin" <pchapin@sover.net>
Subject: Question about controlled types.
Date: Wed, 06 Feb 2008 20:19:32 -0500
Date: 2008-02-06T20:19:32-05:00 [thread overview]
Message-ID: <47aa5ca6$0$32487$4d3efbfe@news.sover.net> (raw)
I'm trying to understand the subtleties of controlled types. In the RM,
section 7.6, paragraph 17 (I'm looking at the Ada 2005 version) I see:
"For an assignment_statement, after the name and expression have been
evaluated, and any conversion (including constraint checking) has been
done, an anonymous object is created, and the value is assigned into it;
that is, the assignment operation is applied. (Assignment includes value
adjustment.) The target of the assignment_statement is then finalized.
The value of the anonymous object is then assigned into the target of
the assignment_statement. Finally, the anonymous object is finalized."
So suppose we have
type Ptr is access Whatever;
type Thing is new Ada.Finalization.Controlled with
record
P : Ptr;
end record;
Thus Things hold a handle to an object allocated on the heap. Now
suppose A and B are Things. Then consider
A := B;
If I understand the paragraph above, an anonymous object is created and
the values of B's components are copied into that object. Adjust is then
used on the anonymous object. Let's imagine that Adjust makes an
independent copy of the object accessed via the P component. If an
exception occurs during this adjustment (Storage_Error, say) the value
of A is not affected. This is good.
Next A is finalized and then the anonymous object is then assigned to A.
Here is my question: is Adjust used again to adjust the value of A? It
would seem so because the anonymous object is finalized after this and
we wouldn't want that finalization to disrupt A's eventual value (assume
Finalize deallocates the object accessed by the P component). However,
if that is all true then why use Adjust on the anonymous object?
It seems to me that a more appropriate sequence of events would be
1. Create the anonymous object as above (using Adjust, etc).
2. Finalize A as above.
3. Copy the components of the anonymous object to A without using Adjust.
4. Don't Finalize the anonymous object.
My concern here is exception safety. I'd like it to be the case that
when I do
A := B;
if there is insufficient memory to build a proper copy of B's complete
representation (including heap structures), I'd like A to be left
unchanged. Yet the semantics described in the RM seem to say that A will
be finalized (thus destroying its value) before the copy of B that
eventually gets stored in A is made. Thus if that copy operation fails
with Storage_Error, A is left corrupted.
This question seems very relevant to the Ada 2005 container library. For
example if A and B are vectors, and if B is a very large vector that I'm
trying to copy, I'd really like for A to be left unchanged should
Storage_Error occur during that copy.
Peter
next reply other threads:[~2008-02-07 1:19 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-02-07 1:19 Peter C. Chapin [this message]
2008-02-07 4:54 ` Question about controlled types Hyman Rosen
2008-02-07 16:30 ` Robert A Duff
2008-02-08 3:31 ` Peter C. Chapin
2008-02-08 3:47 ` Peter C. Chapin
2008-02-07 16:47 ` Adam Beneschan
2008-02-08 3:46 ` Peter C. Chapin
replies disabled
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox