* 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