* Adjust bug? re-post @ 1997-07-19 0:00 Tom Moran 1997-07-19 0:00 ` Robert Dewar 1997-07-20 0:00 ` Tucker Taft 0 siblings, 2 replies; 6+ messages in thread From: Tom Moran @ 1997-07-19 0:00 UTC (permalink / raw) (It seems this post got lost - apologies if you got it twice.) This test program assigns the 'controlled' result from a function to a variable. Two compilers create an intermediate anonymous object and copy and adjust to it before copying and adjusting to the final result. The third compiler does only the final adjust. Is this legal according to 7.6(21)? Making the component 'id' aliased does not change the behavior. The result is that the anonymous object is eventually Finalized without ever having been Initialized or Adjusted, with sad results for my program. Is this a bug in the third compiler, or a legal (though unfortunate) possibility? with ada.finalization; package testc is type c_type is new ada.finalization.controlled with record id:integer:=0; end record; function create return c_type; procedure initialize(x:in out c_type); procedure adjust (x:in out c_type); procedure finalize (x:in out c_type); end testc; with ada.text_io; with ada.unchecked_conversion; package body testc is type a is access all c_type; function showa is new ada.unchecked_conversion(a,long_integer); function create return c_type is newborn:aliased c_type; begin ada.text_io.put_line("creating" & integer'image(newborn.id) & long_integer'image(showa(newborn'unchecked_access))); newborn.id:=7; return newborn; end create; count:natural:=0; procedure initialize(x:in out c_type) is begin count:=count+1;x.id:=count; ada.text_io.put_line("init" & integer'image(x.id) & long_integer'image(showa(x'unchecked_access))); end initialize; procedure adjust (x:in out c_type) is begin ada.text_io.put_line("adj" & integer'image(x.id) & long_integer'image(showa(x'unchecked_access))); end adjust; procedure finalize(x:in out c_type) is begin ada.text_io.put_line("fin" & integer'image(x.id) & long_integer'image(showa(x'unchecked_access))); end finalize; end testc; with ada.text_io,testc; procedure test is procedure try is my_c:testc.c_type; begin ada.text_io.put_line("set"); my_c:=testc.create; ada.text_io.put_line("did it"); end try; begin ada.text_io.put_line("start"); try; ada.text_io.put_line("done"); end test; two compilers questionable compiler start start init 1 39318880 init 1 5897228 set set init 2 39318744 init 2 5897016 creating 2 39318744 creating 2 5897016 adj 7 73084948 fin 1 5897228 fin 7 39318744 adj 7 5897228 fin 1 39318880 fin 7 4587648 adj 7 39318880 did it fin 7 73084948 fin 7 5897228 did it done fin 7 39318880 done ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Adjust bug? re-post 1997-07-19 0:00 Adjust bug? re-post Tom Moran @ 1997-07-19 0:00 ` Robert Dewar 1997-07-19 0:00 ` Tom Moran 1997-07-20 0:00 ` Tom Moran 1997-07-20 0:00 ` Tucker Taft 1 sibling, 2 replies; 6+ messages in thread From: Robert Dewar @ 1997-07-19 0:00 UTC (permalink / raw) Tom Moran says <<This test program assigns the 'controlled' result from a function to a variable. Two compilers create an intermediate anonymous object and copy and adjust to it before copying and adjusting to the final result. The third compiler does only the final adjust. Is this legal according to 7.6(21)? Making the component 'id' aliased does not change the behavior. The result is that the anonymous object is eventually Finalized without ever having been Initialized or Adjusted, with sad results for my program. Is this a bug in the third compiler, or a legal (though unfortunate) possibility? >> This seems obviously legal, and I don't see why you consider it unfortunate. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Adjust bug? re-post 1997-07-19 0:00 ` Robert Dewar @ 1997-07-19 0:00 ` Tom Moran 1997-07-20 0:00 ` Tom Moran 1 sibling, 0 replies; 6+ messages in thread From: Tom Moran @ 1997-07-19 0:00 UTC (permalink / raw) Robert Dewar said: > This seems obviously legal, and I don't see why you consider it unfortunate. type Things is new Ada.Finalization.Controlled with private; procedure Initialize(x:in out Things); procedure Adjust(x:in out Things); procedure Finalize(x:in out Things); type self_access is access all Things; private type Things is new Ada.Finalization.Controlled with record Myself : self_access; end record; ... If both Initialize and Adjust do x.myself := x'unchecked_access; then, since Finalize can never assume that Initialize or Adjust has ever been performed on the object, Finalize can not assume that x.myself = x'unchecked_access This certainly makes it harder to include Things in linked data structures, and I consider that unfortunate. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Adjust bug? re-post 1997-07-19 0:00 ` Robert Dewar 1997-07-19 0:00 ` Tom Moran @ 1997-07-20 0:00 ` Tom Moran 1997-07-21 0:00 ` Tucker Taft 1 sibling, 1 reply; 6+ messages in thread From: Tom Moran @ 1997-07-20 0:00 UTC (permalink / raw) A second problem, unrelated to access pointers, is that Initialize and Adjust become superfluous. Since you can't assume that either has been called for a particular object, every routine that uses an object must first detect whether it was Initialized/Adjusted and if not, do the appropriate things. But that means the sole effect of coding an Initialize/Adjust is a (probably slight) advance in the time at which the object will Initialized/Adjusted. ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Adjust bug? re-post 1997-07-20 0:00 ` Tom Moran @ 1997-07-21 0:00 ` Tucker Taft 0 siblings, 0 replies; 6+ messages in thread From: Tucker Taft @ 1997-07-21 0:00 UTC (permalink / raw) Tom Moran (tmoran@bix.com) wrote: : A second problem, unrelated to access pointers, is that Initialize and : Adjust become superfluous. Since you can't assume that either has been : called for a particular object, every routine that uses an object must : first detect whether it was Initialized/Adjusted and if not, do the : appropriate things. I think you are jumping to conclusions. An object is initialized one of three ways, by default initialization (calls Initialize), by copy (calls Adjust), or by component-by-component initialization (i.e. via an aggregate -- only possible where full definition is visible). The optimization in this case was that the object was *moved*, not that it was created without one of the above 3 actions. If you see movement as inherently creating a new object, then you need to use limited types, or make one of the subcomponents aliased. Normally, however, it shouldn't matter where an object is, so long as it only exists in one place at a given time. It might live in a register for a while, and then in memory for awhile. It might be passed across a network, and then be passed back later. : ... But that means the sole effect of coding an : Initialize/Adjust is a (probably slight) advance in the time at which : the object will Initialized/Adjusted. I think you have missed the nature of the optimization. Compilers are free to move controlled objects around, in general, just like a garbage collector is allowed to "compactify" in some languages. You have to work a little harder if you want to prevent this movement (by making one of the subcomponents aliased). The purpose of "Adjust" is to accommodate the case when there are now two copies of the same value, instead of just one. By contrast, when an object moves, there is still only one value, not two. -- -Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ Intermetrics, Inc. Burlington, MA USA ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: Adjust bug? re-post 1997-07-19 0:00 Adjust bug? re-post Tom Moran 1997-07-19 0:00 ` Robert Dewar @ 1997-07-20 0:00 ` Tucker Taft 1 sibling, 0 replies; 6+ messages in thread From: Tucker Taft @ 1997-07-20 0:00 UTC (permalink / raw) Tom Moran (tmoran@bix.com) wrote: : (It seems this post got lost - apologies if you got it twice.) [I received the original. Here is my original response, with some additional comments in []s:] : This test program assigns the 'controlled' result from a function : to a variable. Two compilers create an intermediate anonymous object : and copy and adjust to it before copying and adjusting to the final : result. The third compiler does only the final adjust. Is this : legal according to 7.6(21)? Yes, it does seem to be legal, provided that the type does not have aliased subcomponents. Declaring the object as a whole as aliased does not inhibit the 7.6(21) optimizations; only the presence of aliased subcomponents does that. : ... Making the component 'id' aliased does : not change the behavior. If a controlled object has an aliased subcomponent, then it should not be moved without being re-adjusted. However, int the code that follows, you have made the object as a whole aliased, but you did not declare the component "id" aliased. Have you tried this with "aliased" on the declaration of "id" itself, as opposed to on the declaration of the object "newborn"? It is certainly the case that this compiler is moving the object newborn to a new location (from 5897016 to 4587648) without re-adjusting it, but that is permitted since it has no aliased subcomponents. However, if you try this again and you add the word "aliased" to the declaration of the "id" component, then you should see different behavior, or else the compiler would be violating the last sentence of 7.6(21). : ... The result is that the anonymous object : is eventually Finalized without ever having been Initialized or : Adjusted, : with sad results for my program. Is this a bug in the third compiler, : or a legal (though unfortunate) possibility? This is not a bug, unless you have tried this with "aliased" in the component declaration for "id". By the way, why are the results "sad" for your program? It may be that what you are doing is generally not portable. However, by declaring one of the components as aliased, you perhaps can make it portable (presuming the compiler properly honors the last sentence of 7.6(21)). [In looking at your second note, I see you are trying to include a self-reference in the object. This was the reason why types with aliased subcomponents were handled specially. So be sure that at least one of the subcomponents is aliased, then the compiler *should* make sure to re-adjust whenever it moves an object. However, I happen to have some inside information on the compiler which you are probably using (;-), and I just checked -- it has a bug in this area. It fails to notice properly the presence of aliased subcomponents. I suspect that in the next release it will do the right thing ;-) ;-).] Alternatively, you might want to change the way you are using the various Initialize/Adjust/Finalize operations. In particular, remember that "Initialize" is only used for default initialization (it might better have been called "Default_Initialize"), and that an aggregate is a way of constructing a controlled object that doesn't result in either a call on (default) Initialize or Adjust for the whole object. (One reason why controlled types should always be private, is that you want to be sure that aggregates are only used inside the definition of the controlled abstraction.) [One final note -- combining self-reference with non-limited controlled types may be stretching things a bit. As you can see, they require that certain "reasonable" optimizations have to be suppressed for them to work properly. Have you considered using limited controlled types? When you put things into linked lists, you are often (though admittedly not always) thinking in terms of lists of identifiable "objects" rather than "values." The basic Ada model is that non-limited types correspond to a value-oriented view, whereas limited types correspond to a view where there are identifiable objects. It is also generally more efficient to have procedures rather than functions as "constructors" for complex objects, or use functions that return pointers rather than values. It would help to understand the ultimate goal of the self-references, etc...] -Tucker Taft stt@inmet.com http://www.inmet.com/~stt/ Intermetrics, Inc. Burlington, MA USA ------ : with ada.finalization; : package testc is : type c_type is new ada.finalization.controlled with record : id:integer:=0; : end record; : function create return c_type; : procedure initialize(x:in out c_type); : procedure adjust (x:in out c_type); : procedure finalize (x:in out c_type); : end testc; : with ada.text_io; : with ada.unchecked_conversion; : package body testc is : type a is access all c_type; : function showa is new ada.unchecked_conversion(a,long_integer); : function create return c_type is : newborn:aliased c_type; : begin : ada.text_io.put_line("creating" & integer'image(newborn.id) & : long_integer'image(showa(newborn'unchecked_access))); : newborn.id:=7; : return newborn; : end create; : count:natural:=0; : procedure initialize(x:in out c_type) is : begin : count:=count+1;x.id:=count; : ada.text_io.put_line("init" : & integer'image(x.id) & : long_integer'image(showa(x'unchecked_access))); : end initialize; : procedure adjust (x:in out c_type) is : begin : ada.text_io.put_line("adj" : & integer'image(x.id) & : long_integer'image(showa(x'unchecked_access))); : end adjust; : procedure finalize(x:in out c_type) is : begin : ada.text_io.put_line("fin" : & integer'image(x.id) & : long_integer'image(showa(x'unchecked_access))); : end finalize; : end testc; : with ada.text_io,testc; : procedure test is : procedure try is : my_c:testc.c_type; : begin : ada.text_io.put_line("set"); : my_c:=testc.create; : ada.text_io.put_line("did it"); : end try; : begin : ada.text_io.put_line("start"); : try; : ada.text_io.put_line("done"); : end test; : two compilers questionable compiler : start start : init 1 39318880 init 1 5897228 : set set : init 2 39318744 init 2 5897016 : creating 2 39318744 creating 2 5897016 : adj 7 73084948 fin 1 5897228 : fin 7 39318744 adj 7 5897228 : fin 1 39318880 fin 7 4587648 : adj 7 39318880 did it : fin 7 73084948 fin 7 5897228 : did it done : fin 7 39318880 : done ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~1997-07-21 0:00 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1997-07-19 0:00 Adjust bug? re-post Tom Moran 1997-07-19 0:00 ` Robert Dewar 1997-07-19 0:00 ` Tom Moran 1997-07-20 0:00 ` Tom Moran 1997-07-21 0:00 ` Tucker Taft 1997-07-20 0:00 ` Tucker Taft
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox