comp.lang.ada
 help / color / mirror / Atom feed
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



             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