TEAM-ADA Archives

Team Ada: Ada Programming Language Advocacy


Options: Use Classic View

Use Monospaced Font
Show Text Part by Default
Show All Mail Headers

Topic: [<< First] [< Prev] [Next >] [Last >>]

Print Reply
Sun, 10 May 1998 03:12:46 -0400
text/plain (66 lines)
>Finalize is called not only at the point of object
>destruction but also at the point of assignment, when the
>value is being overwritten.
  Consider X := Y;
Just before its execution there are two separate and perhaps
differing object X and Y.  The old X must first be destroyed
since it is going to go out of existence.  For instance, if X
is on a linked list, it will need to be unlinked.  So
Finalize is called.  Then the area of memory formerly
occupied by X can be used for a copy of the bits of Y.  At
this point there is only one object, Y, in existence, though
the same bit pattern may be present at X'address.  But if,
say, Y was on a linked list, that list will only have Y, not
the copy.  Then Adjust is called to turn the bit pattern at
X'address into a new object X.  Continuing the linked list
example, Adjust would splice the new X into the list.
(Ignoring the stuff about a temp to allow X := X; to work.)

>which may cause Finalize to be called twice --
The RM explicitly mentions that Finalize may be called
multiple times, so the simple reference counting in the
example won't do.  But you can add
  Has_Been_Finalized : Boolean := False;
to the record definition and start Finalize with
  if Obj.Has_Been_Finalized then return;
  else Obj.Has_Been_Finalized := True;end if;

>Example #1, assume the spec of Final is as given
>But does this make sense?  Null_Finis was never
>Initialized or Adjusted.  Now my ref counts are
>messed up at the end.
  I agree.  It seems it should have been.  And
removing 'constant', or moving from private
spec to body, or adding an 'aliased' component,
none seem to have any affect.

>this instead of returning Null_Finis:
>    return (Controlled with null record);
 =1       in Create, assign to temp
 .0       finalize (controlled with ... ??
 =1       temp->Z1, Adjust
 .0       finalize temp
 :1       initialize Z2
 .0       finalize Z2
 =1       Z1->Z2, adjust
 .0       finalize Z2
 .-1      finalize Z1
>Still end up with that negative one!  And all
>through this section of code, it never thinks
>I have two objects: my ref count is one at most
>the whole time.
  If it had Initialized/Adjusted the (Controlled with ...)
object, or failed to Finalize it, then all would be well.
It seems clear that I/A shouldn't be called on a constant
aggregate (see RM 7.6(11)), but one would think neither
should Finalize.  What happens if Finalize modifies (eg,
a Has_Been_Finalied flag) in the constant aggregate?