* Accessing finalized values
@ 2013-05-02 21:00 sbelmont700
2013-05-02 22:47 ` Adam Beneschan
2013-05-03 22:36 ` Randy Brukardt
0 siblings, 2 replies; 9+ messages in thread
From: sbelmont700 @ 2013-05-02 21:00 UTC (permalink / raw)
Hi,
Does anyone have any insight into what happens if a program uses the value of an object after it has been finalized, but before it ceases to exist? It would seem like a bounded error to do so, but there doesn't seem to be any guidance one way or the other on the matter in the LRM. Clearly it's wouldn't be judicious to do so, but nothing seems to prevent it or even discourage it. Is such a program still legal?
-sb
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-02 21:00 Accessing finalized values sbelmont700
@ 2013-05-02 22:47 ` Adam Beneschan
2013-05-03 22:36 ` Randy Brukardt
1 sibling, 0 replies; 9+ messages in thread
From: Adam Beneschan @ 2013-05-02 22:47 UTC (permalink / raw)
On Thursday, May 2, 2013 2:00:30 PM UTC-7, sbelm...@gmail.com wrote:
> Hi,
>
>
>
> Does anyone have any insight into what happens if a program uses the value of an object after it has been finalized, but before it ceases to exist?
Other than protected types, the only definition of what Finalize does is that a user-defined Finalize routine is called on the object and its subcomponents where it exists. So the effect of accessing it after Finalize is called depends on what Finalize does. Besides that, "finalization" doesn't have any effect on objects or components that aren't controlled or protected, so you should be able to expect that they'll be the same (if not modified by your program) until the object ceases to exist.
A protected operation on a protected object after it's been Finalized raise Program_Error, I believe.
-- Adam
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-02 21:00 Accessing finalized values sbelmont700
2013-05-02 22:47 ` Adam Beneschan
@ 2013-05-03 22:36 ` Randy Brukardt
2013-05-05 15:00 ` sbelmont700
1 sibling, 1 reply; 9+ messages in thread
From: Randy Brukardt @ 2013-05-03 22:36 UTC (permalink / raw)
<sbelmont700@gmail.com> wrote in message
news:143a8db3-c14b-4983-a481-4b998aea42af@googlegroups.com...
>Does anyone have any insight into what happens if a program uses the value
>of an object after it has been finalized, but before it ceases to exist?
Nothing special (other than protected objects, as Adam notes). This is
perfectly legitimate, although arguably pathological. One reason is that it
is legal for Finalize to be called on the same object more than once in
unusual circumstances (this does not necessarily represent a compiler bug).
Moreover, Finalize routines often depend on other data in the program, and
that data might already be finalized (imagine the final finalization of a
program that's completed). It would be hard to get everything into an order
where there was no dependence on things that are already finalized. (This
sort of thing can happen in Claw programs, for instance.) The protected
object case is a bounded error simply because too many implementations
simply crashed in that case (early versions of GNAT did that, it was
horrible trying to figure out why Claw programs wouldn't terminate
properly - the problem was actually our design bug, but its not helpful to
report a bug with a GP fault in the runtime). Making it a bounded error
makes it clear that's not an acceptable implementation. The reference to
"production code" in AARM 9.4(20.h/2) is talking about the locking used in
Claw - which should be obvious from the naming used in the following
example.
Randy.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-03 22:36 ` Randy Brukardt
@ 2013-05-05 15:00 ` sbelmont700
2013-05-06 5:45 ` J-P. Rosen
` (2 more replies)
0 siblings, 3 replies; 9+ messages in thread
From: sbelmont700 @ 2013-05-05 15:00 UTC (permalink / raw)
On Friday, May 3, 2013 6:36:08 PM UTC-4, Randy Brukardt wrote:
>
> This is perfectly legitimate, although arguably pathological.
>
Pathological seems like an understatement; it seems like a pretty major catch-22. If the whole purpose of Finalize is "to ensure that proper cleanup is performed prior to the object becoming permanently inaccessible", but its perfectly legitimate to access the object after Finalize has been called, then writing 110% bulletproof code becomes much more complex. How is an object supposed to free its resources if the resources must still be made available?
For instance, suppose finalization for a File type closes the file; if it has to assume that other code might call Read and Write subprograms after Finalize has been executed, the file must stay open and the point is moot (or it must add preconditions to every operation). It would seem like the same rules for protected types should apply to non-protected types as well, for all the same reasons.
-sb
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-05 15:00 ` sbelmont700
@ 2013-05-06 5:45 ` J-P. Rosen
2013-05-06 8:59 ` Stephen Leake
2013-05-06 9:52 ` Dmitry A. Kazakov
2 siblings, 0 replies; 9+ messages in thread
From: J-P. Rosen @ 2013-05-06 5:45 UTC (permalink / raw)
Le 05/05/2013 17:00, sbelmont700@gmail.com a �crit :
> Pathological seems like an understatement; it seems like a pretty
> major catch-22. If the whole purpose of Finalize is "to ensure that
> proper cleanup is performed prior to the object becoming permanently
> inaccessible", but its perfectly legitimate to access the object
> after Finalize has been called, then writing 110% bulletproof code
> becomes much more complex. How is an object supposed to free its
> resources if the resources must still be made available?
>
> For instance, suppose finalization for a File type closes the file;
> if it has to assume that other code might call Read and Write
> subprograms after Finalize has been executed, the file must stay open
> and the point is moot (or it must add preconditions to every
> operation). It would seem like the same rules for protected types
> should apply to non-protected types as well, for all the same
> reasons.
From a /language/ POV, calling a controlled object after finalization is
allowed. It means that it is up to you to add checks if necessary. In
your example, you would close the file in Finalize, and raise
Program_Error if the local file is closed.
--
J-P. Rosen
Adalog
2 rue du Docteur Lombard, 92441 Issy-les-Moulineaux CEDEX
Tel: +33 1 45 29 21 52, Fax: +33 1 45 29 25 00
http://www.adalog.fr
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-05 15:00 ` sbelmont700
2013-05-06 5:45 ` J-P. Rosen
@ 2013-05-06 8:59 ` Stephen Leake
2013-05-06 9:52 ` Dmitry A. Kazakov
2 siblings, 0 replies; 9+ messages in thread
From: Stephen Leake @ 2013-05-06 8:59 UTC (permalink / raw)
sbelmont700@gmail.com writes:
> On Friday, May 3, 2013 6:36:08 PM UTC-4, Randy Brukardt wrote:
>>
>> This is perfectly legitimate, although arguably pathological.
>>
>
> Pathological seems like an understatement; it seems like a pretty
> major catch-22. If the whole purpose of Finalize is "to ensure that
> proper cleanup is performed prior to the object becoming permanently
> inaccessible", but its perfectly legitimate to access the object after
> Finalize has been called, then writing 110% bulletproof code becomes
> much more complex. How is an object supposed to free its resources if
> the resources must still be made available?
The fact that Finalize is called a second time does _not_ mean the
resources must still be available; it means the rest of the program was
unable to keep proper track of whether Finalize had yet been called.
So it is perfectly fine to do something like:
procedure Finalize (Item : my_type)
is begin
if Item.Finalized then
;; nothing more to do
return;
else
;; free stuff etc
...
end if;
end Finalize;
> For instance, suppose finalization for a File type closes the file; if
> it has to assume that other code might call Read and Write subprograms
> after Finalize has been executed,
It does _not_ have to assume that; it only has to assume that Finalize
might be called again, not any other operation.
--
-- Stephe
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-05 15:00 ` sbelmont700
2013-05-06 5:45 ` J-P. Rosen
2013-05-06 8:59 ` Stephen Leake
@ 2013-05-06 9:52 ` Dmitry A. Kazakov
2013-05-06 20:05 ` sbelmont700
2 siblings, 1 reply; 9+ messages in thread
From: Dmitry A. Kazakov @ 2013-05-06 9:52 UTC (permalink / raw)
On Sun, 5 May 2013 08:00:18 -0700 (PDT), sbelmont700@gmail.com wrote:
> If the whole purpose of Finalize is "to ensure that proper cleanup is
> performed prior to the object becoming permanently inaccessible",
Finalize is a hack. It is not suitable to play the role of a destructor,
though in some cases it could.
> but its
> perfectly legitimate to access the object after Finalize has been called,
That depends on the role Finalize to play. There is no language guarantee
for Finalize to act as a destructor, which would mean in particular that no
operation of the type T will be called after destruction of T.
BTW, this does not imply you could not access operations of its parent
types. That happens only after the parent's destructor is done.
If you want Finalize to act as a destructor it becomes your responsibility,
because the language lend very little support here.
> then writing 110% bulletproof code becomes much more complex. How is an
> object supposed to free its resources if the resources must still be made
> available?
It must not, because the language does not require either behavior. E.g.
task components are not available after Finalize in the sense that you
cannot call to their entry points. Though you still can query some
attributes of. As others have pointed out you have to add some additional
logic in order to make working better. You will never have a bulletproof
code because construction/destruction in Ada is broken/unsupported in too
many places.
--
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-06 9:52 ` Dmitry A. Kazakov
@ 2013-05-06 20:05 ` sbelmont700
2013-05-07 0:51 ` Randy Brukardt
0 siblings, 1 reply; 9+ messages in thread
From: sbelmont700 @ 2013-05-06 20:05 UTC (permalink / raw)
On Monday, May 6, 2013 5:52:18 AM UTC-4, Dmitry A. Kazakov wrote:
>
> Finalize is a hack.
>
The more I delve into controlled types, the more I'm starting to come to that conclusion. This means, in general, that every controlled type must track the state of its finalization and conditionally release resources (to side-step the non-limited multiple finalization issue), as well as add a 'not Is_Finalized' precondition to every single operation (to avoid access after finalization)? Yuck.
-sb
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: Accessing finalized values
2013-05-06 20:05 ` sbelmont700
@ 2013-05-07 0:51 ` Randy Brukardt
0 siblings, 0 replies; 9+ messages in thread
From: Randy Brukardt @ 2013-05-07 0:51 UTC (permalink / raw)
<sbelmont700@gmail.com> wrote in message
news:56ae2d39-e3a1-4d3e-b9a1-8d4aa435ad8a@googlegroups.com...
On Monday, May 6, 2013 5:52:18 AM UTC-4, Dmitry A. Kazakov wrote:
>> Finalize is a hack.
I disagree with this...
>The more I delve into controlled types, the more I'm starting to come to
>that
> conclusion. This means, in general, that every controlled type must track
> the
> state of its finalization and conditionally release resources (to
> side-step the
> non-limited multiple finalization issue), as well as add a 'not
> Is_Finalized'
> precondition to every single operation (to avoid access after
> finalization)?
> Yuck.
...but disagree with this. And the main reason is that you have to be able
to handle "non-open" objects in any case (consider files -- you have to
already have some sort of check for an unopen file). So there is no problem
to using that same check for objects that have been finalized.
For instance, in Claw, we have "invalid" objects, which is any object that
exists, but has not yet been created or has previously been closed (which
included finalization). Finalization releases resources making the object
invalid. Every operation (other than Create, Close, and Finalize) have to
check for whether the object is valid, and raise an exception if it is not.
Care must be taken to avoid referencing any components if the object is
invalid. There's certainly some level of complication to that, but it's
unavoidable for any abstraction that has something like Create and/or Close.
It might be more of a problem for abstractions that don't have "Close", but
even there there is usually an "empty" abstraction which also works fine.
For instance, the Ada containers work this way: they're initialized to
empty, and end up empty after finalization, and that's sufficient if the
implementation can avoid using an extra resources for an empty container.
(If you can't do this, the language requires raising an exception on use, so
you'd have to have an extra flag and check.)
To summarize, it's a level of complication, but its one you're almost
certainly going to have to deal with anyway. The main problem is that it
makes most simplistic examples wrong - real examples need checks everywhere
anyway (if they're a well-designed Ada abstraction).
Randy.
-sb
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2013-05-07 0:51 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-05-02 21:00 Accessing finalized values sbelmont700
2013-05-02 22:47 ` Adam Beneschan
2013-05-03 22:36 ` Randy Brukardt
2013-05-05 15:00 ` sbelmont700
2013-05-06 5:45 ` J-P. Rosen
2013-05-06 8:59 ` Stephen Leake
2013-05-06 9:52 ` Dmitry A. Kazakov
2013-05-06 20:05 ` sbelmont700
2013-05-07 0:51 ` Randy Brukardt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox