>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 >... >end >.-1 >... >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); Z =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 end > >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?