* Re: Free'ing extended types @ 1996-04-28 0:00 Jonas Nygren 1996-04-28 0:00 ` Robert Dewar 0 siblings, 1 reply; 21+ messages in thread From: Jonas Nygren @ 1996-04-28 0:00 UTC (permalink / raw) I forward this on the request of Laurent. : Laurent Guerby wrote: : > Jonas Nygren writes : > : I read the following in the RM on unchecked_deallocation: : > : : > : 13.11.2(16) : > : .... The execution of a call to an instance of : > : Unchecked_Deallocation is erroneous if the object : > : was created other than by an allocator for an : > : access type whose pool is Name'Storage_Pool. [deleted] : Sorry, I got my example code wrong, it should have been: : : procedure free is new unchecked_deallocation(a'Class, ap); : : 13.11.2(16) talks about 'erroneous execution', i.e. an error which the : compiler can/need not detect. In the example 'p' is a pointer to a'class : and when the call to free is made it actually points to an instance of : type 'b'. So the question is, could this be considered an erroneous : execution? I *think* that it (erroneous/not erroneous) is implementation dependant, because for each access type the Storage_Pool (if not user-specified) is choosen "in an implementation-defined manner", see 13.11(17). This has to be documented for each compiler. In the case of GNAT, here is the code for Unchecked_Deallocation : with System; procedure Unchecked_Deallocation (X : in out Name) is procedure Free (A : System.Address); pragma Import (C, Free); begin if X /= null then Free (X.all'Address); X := null; end if; end Unchecked_Deallocation; So there's nothing that could lead to an erroneous execution (note the X.all'access, the libc then does what's needed). : /jonas PS: this is of general interest, please post your correction and my answer to comp.lang.ada for verification (legality stuff and GNAT stuff) for me, my news server is down this week-end. Thank you. -- -- Laurent Guerby, student at Telecom Bretagne (France), Team Ada. -- "Use the Source, Luke. The Source will be with you, always (GPL)." -- http://www-eleves.enst-bretagne.fr/~guerby/ (GATO Project). -- Try GNAT, the GNU Ada 95 compiler (ftp://cs.nyu.edu/pub/gnat). ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-28 0:00 Free'ing extended types Jonas Nygren @ 1996-04-28 0:00 ` Robert Dewar 1996-04-29 0:00 ` Laurent Guerby ` (2 more replies) 0 siblings, 3 replies; 21+ messages in thread From: Robert Dewar @ 1996-04-28 0:00 UTC (permalink / raw) Jonas said " So there's nothing that could lead to an erroneous execution (note the X.all'access, the libc then does what's needed)." You seem to have the wrong idea of what erroneous is about. An erroneous execution is one whose semantics is not specified by the reference manual. You seem to think this means that it wlil blow up or do something wrong. Not at all! It *may* blow up but it does not have to! You can look at the execution of a particular impementation and conclude that a particular erroneous execution will have no ill effect on that implementation, but that does not mean that the exeution is not erroneous! This is one of these places where no amount of testing can help, only a detailed knowledge of the formal semantics of the refrence manual can tell you if a given execution is indeed erroneous -- it is not something you can (necessarily) observe. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-28 0:00 ` Robert Dewar @ 1996-04-29 0:00 ` Laurent Guerby 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Jonas Nygren 1996-04-29 0:00 ` Free'ing extended types Laurent Guerby 2 siblings, 1 reply; 21+ messages in thread From: Laurent Guerby @ 1996-04-29 0:00 UTC (permalink / raw) Jonas Nygren writes [deleted complete Bob's crystal-clear explanations ;-] : Yes, I think it would be nice. Every now and then I start thinking : of defining my own language and implement it always with GC as a : basic feature. But then it always stops at the thought because : of the sheer complexity of the task. [deleted] Note that the impact of a GC on the "erronenousness" of a program is interesting. An Ada run-time with GC can simply ignore Unchecked_Dealocation calls, or do smart thing and raise Program_Error when an access to a previously deallocated object is performed. In the first case (do nothing on deallocation) I think the execution is not erroneous because RM95-13.11.2(16) says : "Evaluating a name that denotes a nonexistent object is erroneous. The execution of a call to an instance of Unchecked_Deallocation is erroneous if the object was created other than by an allocator for an access type whose pool is Name'Storage_Pool." On a garbage collected implementation, the object is likely to be "existant" or your GC is wrong ;-). : /jonas -- -- Laurent Guerby, student at Telecom Bretagne (France), Team Ada. -- "Use the Source, Luke. The Source will be with you, always (GPL)." -- http://www-eleves.enst-bretagne.fr/~guerby/ (GATO Project). -- Try GNAT, the GNU Ada 95 compiler (ftp://cs.nyu.edu/pub/gnat). ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-29 0:00 ` Laurent Guerby @ 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Robert Dewar 0 siblings, 1 reply; 21+ messages in thread From: Robert A Duff @ 1996-04-29 0:00 UTC (permalink / raw) In article <4xpw8qvlau.fsf@lagrange.enst-bretagne.fr>, Laurent Guerby <Laurent.Guerby@enst-bretagne.fr> wrote: > Note that the impact of a GC on the "erronenousness" of a program >is interesting. An Ada run-time with GC can simply ignore >Unchecked_Dealocation calls, or do smart thing and raise Program_Error >when an access to a previously deallocated object is performed. In the >first case (do nothing on deallocation) I think the execution is not >erroneous because RM95-13.11.2(16) says : > >"Evaluating a name that denotes a nonexistent object is erroneous. >The execution of a call to an instance of Unchecked_Deallocation is >erroneous if the object was created other than by an allocator for an >access type whose pool is Name'Storage_Pool." > > On a garbage collected implementation, the object is likely to be >"existant" or your GC is wrong ;-). No, I don't think so. The RM says an Unchecked_Deallocated object is non-existent, and deallocating it is erroneous. If you have a GC that thinks it still exists, that's fine, but it's irrelevant to the formal definition of erroneous. (In this case I'd like the gc to raise an exception, but of course that's not required, since erroneous means *anything* can happen, including keeping the officially deallocated object around and using it as usual.) - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-29 0:00 ` Robert A Duff @ 1996-04-29 0:00 ` Robert Dewar 0 siblings, 0 replies; 21+ messages in thread From: Robert Dewar @ 1996-04-29 0:00 UTC (permalink / raw) Bob Duff said "No, I don't think so. The RM says an Unchecked_Deallocated object is non-existent, and deallocating it is erroneous. If you have a GC that thinks it still exists, that's fine, but it's irrelevant to the formal definition of erroneous. (In this case I'd like the gc to raise an exception, but of course that's not required, since erroneous means *anything* can happen, including keeping the officially deallocated object around and using it as usual.)" Exactly! The definition of what is erroneous and what is not is a function of the semantics of the language (in some cases, as has been pointed out it is non-deterministic whether or not the execution is erroneous, since it depends on implementation choices). But GC does NOT alter the semantics of unchecked deallocatoin at all, and so is irrelevant to the consideration of whether or not a program using unchecked deallocation is or is not erroneous ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-28 0:00 ` Robert Dewar 1996-04-29 0:00 ` Laurent Guerby @ 1996-04-29 0:00 ` Jonas Nygren 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Free'ing extended types Laurent Guerby 2 siblings, 1 reply; 21+ messages in thread From: Jonas Nygren @ 1996-04-29 0:00 UTC (permalink / raw) Robert Dewar wrote: > > Jonas said > > " So there's nothing that could lead to an erroneous execution > (note > the X.all'access, the libc then does what's needed)." I think the above quote is from Laurent Guerby. > > You seem to have the wrong idea of what erroneous is about. An erroneous > execution is one whose semantics is not specified by the reference > manual. You seem to think this means that it wlil blow up or do > something wrong. Not at all! It *may* blow up but it does not have to! Murphy's law: If it can blow up - it will blow up. I personally take a very simplistic approach to never use a construct that I know can blow up. > > You can look at the execution of a particular impementation and conclude > that a particular erroneous execution will have no ill effect on that > implementation, but that does not mean that the exeution is not erroneous! Well, I am aiming for portable code and free'ing memory can have great effect on the program structure. I don't want to have to rewrite my code between different language implementations. > > This is one of these places where no amount of testing can help, only > a detailed knowledge of the formal semantics of the refrence manual > can tell you if a given execution is indeed erroneous -- it is not something > you can (necessarily) observe. That is what my original question was all about. A pity you did not have an anwer to that - I guess you have the "detailed knowledge of the formal semantics" of Ada to respond to my question. I repeat my original question here: with Ada.Unchecked_Deallocation; procedure St is type a is tagged record X : Integer; end record; type ap is access all a'class; procedure free is new Ada.unchecked_deallocation(A'class, ap); type b is new a with record Y : Integer; end record; -- a is extended p : ap := new b; begin free(p); -- erroneous ?? end St; Could the call on free result in erroneous execution (in any conceivable law abiding implementation of Ada). /jonas ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-29 0:00 ` Jonas Nygren @ 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Jonas Nygren ` (2 more replies) 0 siblings, 3 replies; 21+ messages in thread From: Robert A Duff @ 1996-04-29 0:00 UTC (permalink / raw) In article <3184803D.1208@ehs.ericsson.se>, Jonas Nygren <ehsjony@ehs.ericsson.se> wrote: >Robert Dewar wrote: >> You seem to have the wrong idea of what erroneous is about. An erroneous >> execution is one whose semantics is not specified by the reference >> manual. You seem to think this means that it wlil blow up or do >> something wrong. Not at all! It *may* blow up but it does not have to! Robert is correct in general about erroneousness, but in *this* case, the RM actually says that it's erroneous on some implementations, and not others. >Murphy's law: If it can blow up - it will blow up. In a way, you're lucky if it *does* blow up. Sometimes, it works fine. Until some customer gets ahold of the code, or until somebody tries to port the code, or you get an updated compiler or something (and the original programmer has moved to Mars). >I personally take a very simplistic approach to never use a construct >that I know can blow up. Not even by accident? ;-) >I repeat my original question here: OK, I'll try to answer. Each access type has a storage pool. Pools can be shared among many access types. However, a *single* access type has exactly one pool. There is only one access type in your example, so, clearly everything is allocated in the same pool. So your example is *not* erroneous. The fact that this pool contains A's and B's is irrelevant -- what matters is the access type. >with Ada.Unchecked_Deallocation; >procedure St is > type a is tagged record X : Integer; end record; > type ap is access all a'class; > procedure free is new Ada.unchecked_deallocation(A'class, ap); > type b is new a with record > Y : Integer; end record; -- a is extended > > p : ap := new b; >begin > free(p); -- erroneous ?? >end St; > >Could the call on free result in erroneous execution (in any conceivable >law abiding implementation of Ada). No. However, consider: with Ada.Unchecked_Deallocation; procedure St is type a is tagged record X : Integer; end record; type ap is access all a'class; procedure free is new Ada.unchecked_deallocation(A'class, ap); type b is new a with record Y : Integer; end record; -- a is extended type BP is access all B'Class; -- ADDED THIS p : BP := new b; -- CHANGED THIS q: AP := AP(p); -- ADDED THIS begin free(Q); -- erroneous ?? -- CHANGED THIS end St; Now, Q is being freed from a different access type than the one for which it was allocated. It is implementation-defined whether or not this is erroneous! (Which is subtly different from just being plain old erroneous.) This is because it is implementation defined whether AP and BP share the same pool. In retrospect, I believe this is a language design flaw, for obvious reasons. However, there is probably a de-facto standard. I would be very surprised if AP and BP did *not* share the same pool in any implementation. (Any implementers care to comment?) To be safe: Given a hierarchy of tagged types, allocate them all using the *same* access type. Then, if necessary, convert this to whatever other access types you like. When deallocating, convert things back to the original access type. And put all the allocation and deallocation in a single package, so you easily manage these conventions, and you won't screw up by mistake. (That's a good idea anyway -- e.g. you might want to instrument allocations someday, so you can tell how much memory you're allocating, or track down storage leaks, or whatever.) Alternatively, you can say things like "for BP'Storage_Pool use AP'Storage_Pool;". Or, you could say "for BP'Storage_Size use 0;", which will prevent people from accidentally allocating using type BP, assuming your convention is to always use type AP. To be safer: Buy a compiler with garbage collection. ;-) - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-29 0:00 ` Robert A Duff @ 1996-04-29 0:00 ` Jonas Nygren 1996-04-29 0:00 ` Robert Dewar 1996-05-20 0:00 ` Type conversion between access types (was: Free'ing extended types) Scott Leschke 2 siblings, 0 replies; 21+ messages in thread From: Jonas Nygren @ 1996-04-29 0:00 UTC (permalink / raw) To: Robert A Duff Robert A Duff wrote: > > In article <3184803D.1208@ehs.ericsson.se>, > Jonas Nygren <ehsjony@ehs.ericsson.se> wrote: > >Robert Dewar wrote: > >> You seem to have the wrong idea of what erroneous is about. An erroneous > >> execution is one whose semantics is not specified by the reference > >> manual. You seem to think this means that it wlil blow up or do > >> something wrong. Not at all! It *may* blow up but it does not have to! > > Robert is correct in general about erroneousness, but in *this* case, > the RM actually says that it's erroneous on some implementations, and > not others. > > >Murphy's law: If it can blow up - it will blow up. > > In a way, you're lucky if it *does* blow up. Sometimes, it works fine. > Until some customer gets ahold of the code, or until somebody tries to > port the code, or you get an updated compiler or something (and the > original programmer has moved to Mars). > > >I personally take a very simplistic approach to never use a construct > >that I know can blow up. > > Not even by accident? ;-) Well, I actually put in the 'know' to cover my ass :-) > > >I repeat my original question here: > > OK, I'll try to answer. Each access type has a storage pool. Pools can > be shared among many access types. However, a *single* access type has > exactly one pool. There is only one access type in your example, so, > clearly everything is allocated in the same pool. So your example is > *not* erroneous. The fact that this pool contains A's and B's is > irrelevant -- what matters is the access type. > > >with Ada.Unchecked_Deallocation; > >procedure St is > > type a is tagged record X : Integer; end record; > > type ap is access all a'class; > > procedure free is new Ada.unchecked_deallocation(A'class, ap); > > type b is new a with record > > Y : Integer; end record; -- a is extended > > > > p : ap := new b; > >begin > > free(p); -- erroneous ?? > >end St; > > > >Could the call on free result in erroneous execution (in any conceivable > >law abiding implementation of Ada). > > No. > > However, consider: > > with Ada.Unchecked_Deallocation; > procedure St is > type a is tagged record X : Integer; end record; > type ap is access all a'class; > procedure free is new Ada.unchecked_deallocation(A'class, ap); > type b is new a with record > Y : Integer; end record; -- a is extended > type BP is access all B'Class; -- ADDED THIS > > p : BP := new b; -- CHANGED THIS > q: AP := AP(p); -- ADDED THIS > begin > free(Q); -- erroneous ?? -- CHANGED THIS > end St; > > Now, Q is being freed from a different access type than the one for > which it was allocated. It is implementation-defined whether or not > this is erroneous! (Which is subtly different from just being plain old > erroneous.) This is because it is implementation defined whether AP and > BP share the same pool. In retrospect, I believe this is a language > design flaw, for obvious reasons. Agreed! > > However, there is probably a de-facto standard. I would be very > surprised if AP and BP did *not* share the same pool in any > implementation. (Any implementers care to comment?) > > To be safe: Given a hierarchy of tagged types, allocate them all using > the *same* access type. Then, if necessary, convert this to whatever > other access types you like. When deallocating, convert things back to > the original access type. And put all the allocation and deallocation > in a single package, so you easily manage these conventions, and you > won't screw up by mistake. (That's a good idea anyway -- e.g. you might > want to instrument allocations someday, so you can tell how much memory > you're allocating, or track down storage leaks, or whatever.) > > Alternatively, you can say things like "for BP'Storage_Pool use > AP'Storage_Pool;". Or, you could say "for BP'Storage_Size use 0;", > which will prevent people from accidentally allocating using type BP, > assuming your convention is to always use type AP. > > To be safer: Buy a compiler with garbage collection. ;-) Yes, I think it would be nice. Every now and then I start thinking of defining my own language and implement it always with GC as a basic feature. But then it always stops at the thought because of the sheer complexity of the task. > > - Bob Thanks for the complete answer! /jonas ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Jonas Nygren @ 1996-04-29 0:00 ` Robert Dewar 1996-04-29 0:00 ` Robert A Duff 1996-05-20 0:00 ` Type conversion between access types (was: Free'ing extended types) Scott Leschke 2 siblings, 1 reply; 21+ messages in thread From: Robert Dewar @ 1996-04-29 0:00 UTC (permalink / raw) Bob Duff said "Robert is correct in general about erroneousness, but in *this* case, the RM actually says that it's erroneous on some implementations, and not others." Yes indeed, it can be implementation dependent whether or not the semantics leads to erroneous execution in the case where the semantics is itself deliberately implementation dependent as in this case. What I was saying was that you can never look to the actual code in the implementation to determine this, though you could look to annex M. ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-29 0:00 ` Robert Dewar @ 1996-04-29 0:00 ` Robert A Duff 0 siblings, 0 replies; 21+ messages in thread From: Robert A Duff @ 1996-04-29 0:00 UTC (permalink / raw) In article <dewar.830797117@schonberg>, Robert Dewar <dewar@cs.nyu.edu> wrote: >What I was saying was that you can never look to the actual code in >the implementation to determine this, though you could look to annex M. Yes, quite correct, and quite a useful admonishment. Too many folks program by seeing what a particular implementation does, and then assuming that's what all implementations will do! I guess I'm off-topic here, since this affliction is prevalent among programmers in just about *all* languages, not particularly Ada. Grump. ;-) - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Type conversion between access types (was: Free'ing extended types) 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Jonas Nygren 1996-04-29 0:00 ` Robert Dewar @ 1996-05-20 0:00 ` Scott Leschke 1996-05-21 0:00 ` Dale Stanbrough 1996-05-21 0:00 ` Robert A Duff 2 siblings, 2 replies; 21+ messages in thread From: Scott Leschke @ 1996-05-20 0:00 UTC (permalink / raw) On a related but different note, I was wondering about the effect of the reserved word 'all' in the access type declarations below. First I was slightly surprised that the type conversions in the example code Bob Duff posted were allowed since I know that independent access types (even those specifying the same type) are viewed as denoting separate pools and as such type conversions between them is not allowed. This rule appears to go out the window though if the 'all' modifier is used as in Bob's example. To paraphrase Jerry Seinfeld, "What's the deal with that?" If you remove the 'all's from the declarations, the example ceases to compile using GNAT 3.03 SunOS 4.1.3 giving the error message: ./pool_test.adb:19:14: invalid conversion, not compatible with type "BP" defined at line X. To sumarize: with Ada.Unchecked_Deallocation; procedure St is type a is tagged record X : Integer; end record; type ap is access a'class; procedure free is new Ada.unchecked_deallocation(A'class, ap); type b is new a with record Y : Integer; end record; -- a is extended type BP is access B'Class; -- ADDED THIS p : BP := new b; -- CHANGED THIS q: AP := AP(p); -- ADDED THIS begin free(Q); -- erroneous ?? -- CHANGED THIS end St; gives: ./pool_test.adb:19:14: invalid conversion, not compatible with type "BP" defined at line X. BTW, If this is by some off chance highlights a bug in GNAT, please accept my apologies up front for wasting bandwidth in this forum, but I don't believe it is. bobduff@world.std.com (Robert A Duff) writes: >However, consider: >with Ada.Unchecked_Deallocation; >procedure St is > type a is tagged record X : Integer; end record; > type ap is access all a'class; > procedure free is new Ada.unchecked_deallocation(A'class, ap); > type b is new a with record > Y : Integer; end record; -- a is extended > type BP is access all B'Class; -- ADDED THIS > p : BP := new b; -- CHANGED THIS > q: AP := AP(p); -- ADDED THIS >begin > free(Q); -- erroneous ?? -- CHANGED THIS >end St; [..] Other stuff omitted >- Bob -- Scott Leschke.........................email: leschkes@cig.mot.com Motorola, Inc............................ph: 847-632-2786 1501 W Shure Drive......................fax: 847-632-3145 Arlington Heights, IL 60004......mailstop: 1301 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-20 0:00 ` Type conversion between access types (was: Free'ing extended types) Scott Leschke @ 1996-05-21 0:00 ` Dale Stanbrough 1996-05-21 0:00 ` Robert A Duff 1996-05-21 0:00 ` Robert A Duff 1 sibling, 1 reply; 21+ messages in thread From: Dale Stanbrough @ 1996-05-21 0:00 UTC (permalink / raw) Scott Leschke writes: "First I was slightly surprised that the type conversions in the example code Bob Duff posted were allowed since I know that independent access types (even those specifying the same type) are viewed as denoting separate pools and as such type conversions between them is not allowed." I presume that this also means that access types declared inside a generic package are not compatable with other access types? e.g. generic type element is private; package x is type ptr is access element; end; package y is type a is private; type ptr is access a; package new_ptr_package is new x(a); end; Is new_ptr_package.ptr not type convertible with y.ptr? Is it likely that compilers would use different storage pools for these two types? Dale ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-21 0:00 ` Dale Stanbrough @ 1996-05-21 0:00 ` Robert A Duff 0 siblings, 0 replies; 21+ messages in thread From: Robert A Duff @ 1996-05-21 0:00 UTC (permalink / raw) In article <4nr20u$mv9@goanna.cs.rmit.EDU.AU>, Dale Stanbrough <dale@goanna.cs.rmit.EDU.AU> wrote: >Is new_ptr_package.ptr not type convertible with y.ptr? No, it is not convertible. If you add "all", then it is. >Is it likely that compilers would use different storage pools for >these two types? No. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-20 0:00 ` Type conversion between access types (was: Free'ing extended types) Scott Leschke 1996-05-21 0:00 ` Dale Stanbrough @ 1996-05-21 0:00 ` Robert A Duff 1996-05-22 0:00 ` Scott Leschke 1 sibling, 1 reply; 21+ messages in thread From: Robert A Duff @ 1996-05-21 0:00 UTC (permalink / raw) In article <leschkes.832628057@ferret>, Scott Leschke <leschkes@ferret.cig.mot.com> wrote: >On a related but different note, I was wondering about the effect of the >reserved word 'all' in the access type declarations below. First I was >slightly surprised that the type conversions in the example code Bob Duff >posted were allowed since I know that independent access types (even those >specifying the same type) are viewed as denoting separate pools and as such >type conversions between them is not allowed. This rule appears to go out >the window though if the 'all' modifier is used as in Bob's example. To >paraphrase Jerry Seinfeld, "What's the deal with that?" Yes, if you add the 'all' modifier, the restriction goes "out the window". You can convert *to* an 'all' access type, so long as the designated subtypes match. But you had better be careful about storage pools -- if you deallocate from the wrong type, it's erroneous. >If you remove the 'all's from the declarations, the example ceases to >compile using GNAT 3.03 SunOS 4.1.3 giving the error message: Right. >BTW, If this is by some off chance highlights a bug in GNAT, please accept >my apologies up front for wasting bandwidth in this forum, but I don't >believe it is. I believe GNAT is correct here. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-21 0:00 ` Robert A Duff @ 1996-05-22 0:00 ` Scott Leschke 1996-05-23 0:00 ` Robert A Duff 0 siblings, 1 reply; 21+ messages in thread From: Scott Leschke @ 1996-05-22 0:00 UTC (permalink / raw) bobduff@world.std.com (Robert A Duff) writes: >Yes, if you add the 'all' modifier, the restriction goes "out the >window". You can convert *to* an 'all' access type, so long as the >designated subtypes match. But you had better be careful about storage >pools -- if you deallocate from the wrong type, it's erroneous. So what about 'all' causes the conversion to be allowed? I looked at section 4.6 of the LRM but got a tad confused? -- Scott Leschke.........................email: leschkes@cig.mot.com Motorola, Inc............................ph: 847-632-2786 1501 W Shure Drive......................fax: 847-632-3145 Arlington Heights, IL 60004......mailstop: 1301 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-22 0:00 ` Scott Leschke @ 1996-05-23 0:00 ` Robert A Duff 1996-05-23 0:00 ` progers 1996-05-24 0:00 ` Scott Leschke 0 siblings, 2 replies; 21+ messages in thread From: Robert A Duff @ 1996-05-23 0:00 UTC (permalink / raw) In article <leschkes.832803959@ferret>, Scott Leschke <leschkes@ferret.cig.mot.com> wrote: >So what about 'all' causes the conversion to be allowed? I looked at >section 4.6 of the LRM but got a tad confused? If you write "all", then it's called a "general access type". 4.6(13) allows conversion from an access type (general or pool-specific) to a general access type. 4.6(21) says that if the target type doesn't fall into one the cases allowed previously, then you can only convert within the same tree of derived types. (I suspect that derived access types are unusual, so that would probably not apply.) In retrospect, I think the added complexity of "all" was a mistake. We should have dropped the "all", and just let 4.6(13) apply to any access type. The intention of having the "all" in the language was to allow implementations to use clever representations for pool-specific access types. For example, if you know that the storage pool is only 64 K bytes, then you can use a 16-bit offset for a pool-specific access type, because you know it always points into that pool. For a general access type, however, you need a full pointer (say, 32 bits), because it can point into any pool, and can point into the stack. Another advantage of pool-specific access types is that you know you can't erroneously deallocate from the wrong storage pool. But in my programs, I almost always end up writing "all". I suggest that you always use "all" for access-to-class-wide types, since you will often need to do the conversions allowed by 4.6(13). - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-23 0:00 ` Robert A Duff @ 1996-05-23 0:00 ` progers 1996-05-24 0:00 ` Scott Leschke 1 sibling, 0 replies; 21+ messages in thread From: progers @ 1996-05-23 0:00 UTC (permalink / raw) In <Drv666.92J@world.std.com>, bobduff@world.std.com (Robert A Duff) writes: >In article <leschkes.832803959@ferret>, >Scott Leschke <leschkes@ferret.cig.mot.com> wrote: >>So what about 'all' causes the conversion to be allowed? I looked at >>section 4.6 of the LRM but got a tad confused? > >If you write "all", then it's called a "general access type". 4.6(13) >allows conversion from an access type (general or pool-specific) to a >general access type. 4.6(21) says that if the target type doesn't fall >into one the cases allowed previously, then you can only convert within >the same tree of derived types. (I suspect that derived access types >are unusual, so that would probably not apply.) Derived access type conversion is unusual, at least in my experience, but it sure is handy when you need it (in this case to prevent infinite recursion on "="): package Dynamic_Strings is type Text is limited private; function "="( Left, Right : Text ) return Boolean; ... private type Internal is access String; type Text is new Internal; end Dynamic_Strings; package body Dynamic_Strings is function "="( Left, Right : Text ) return Boolean is begin if ( Internal(Left) = null ) and ( Internal(Right) = null ) then return True; elsif ( Internal(Left) = null ) xor ( Internal(Right) = null ) then return False; -- since one points to an object & the other to nada else -- both refer to objects... return ( Left.all = Right.all ); end if; end "="; ... end Dynamic_Strings; pat --------------- Patrick Rogers progers@acm.org ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-23 0:00 ` Robert A Duff 1996-05-23 0:00 ` progers @ 1996-05-24 0:00 ` Scott Leschke 1996-05-24 0:00 ` Robert A Duff 1 sibling, 1 reply; 21+ messages in thread From: Scott Leschke @ 1996-05-24 0:00 UTC (permalink / raw) bobduff@world.std.com (Robert A Duff) writes: [...] Some good stuff >The intention of having the "all" in the language was to allow >implementations to use clever representations for pool-specific access >types. For example, if you know that the storage pool is only 64 K >bytes, then you can use a 16-bit offset for a pool-specific access type, >because you know it always points into that pool. For a general access >type, however, you need a full pointer (say, 32 bits), because it can >point into any pool, and can point into the stack. Yeah, I saw this point made in the Rationale. >Another advantage of pool-specific access types is that you know you >can't erroneously deallocate from the wrong storage pool. >But in my programs, I almost always end up writing "all". I suggest >that you always use "all" for access-to-class-wide types, since you will >often need to do the conversions allowed by 4.6(13). I have noticed that in most of the code I've seen, all is used pretty liberally would makes me wonder about the benefit of making the distinction between pool and general accesss types myself. I have wondered if it may have been better to have the distinction go the other way if indeed a distinction was warranted (ie. general and non-pool based). -- Scott Leschke.........................email: leschkes@cig.mot.com Motorola, Inc............................ph: 847-632-2786 1501 W Shure Drive......................fax: 847-632-3145 Arlington Heights, IL 60004......mailstop: 1301 ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Type conversion between access types (was: Free'ing extended types) 1996-05-24 0:00 ` Scott Leschke @ 1996-05-24 0:00 ` Robert A Duff 0 siblings, 0 replies; 21+ messages in thread From: Robert A Duff @ 1996-05-24 0:00 UTC (permalink / raw) In article <leschkes.832959439@ferret>, Scott Leschke <leschkes@ferret.cig.mot.com> wrote: >I have noticed that in most of the code I've seen, all is used pretty >liberally would makes me wonder about the benefit of making the distinction >between pool and general accesss types myself. I have wondered if it may >have been better to have the distinction go the other way if indeed a >distinction was warranted (ie. general and non-pool based). I admit, with 20-20 hindsight, that the 'all' thing was a mistake. I pushed for the idea during the design of Ada 9X, because I thought this efficiency distinction was important. Tucker, on the other hand, thought that all access types should be 'all'. He was right; I was wrong. - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-28 0:00 ` Robert Dewar 1996-04-29 0:00 ` Laurent Guerby 1996-04-29 0:00 ` Jonas Nygren @ 1996-04-29 0:00 ` Laurent Guerby 1996-04-29 0:00 ` Robert A Duff 2 siblings, 1 reply; 21+ messages in thread From: Laurent Guerby @ 1996-04-29 0:00 UTC (permalink / raw) Robert Dewar writes : Jonas said ^^^^^ Jonas posted my email ;-). : " So there's nothing that could lead to an erroneous execution : (note : the X.all'access, the libc then does what's needed)." : : You seem to have the wrong idea of what erroneous is about. An erroneous : execution is one whose semantics is not specified by the reference : manual. You seem to think this means that it wlil blow up or do : something wrong. Not at all! It *may* blow up but it does not have to! : : You can look at the execution of a particular impementation and conclude : that a particular erroneous execution will have no ill effect on that : implementation, but that does not mean that the exeution is not erroneous! I think you missed my answer, I was just saying that, in this case, the "erroneous execution" was implementation dependant : " I *think* that it (erroneous/not erroneous) is implementation dependant, because for each access type the Storage_Pool (if not user-specified) is choosen "in an implementation-defined manner", see 13.11(17)." And I was pointing out the GNAT sources showing (I'm not 100% sure of my interpretation here) the use of one Storage_Pool (coded from the C library) for all these types. My conclusion was that the construction was not erroneous for the GNAT compiler. If another Ada compiler use different pools for the types in the example, as permitted by the RM 13.11(17), then the execution of the construct is erroneous. Then, of course, it can just work, don't work, crash your disk or nicely dies with Program_Error ;-). -- -- Laurent Guerby, student at Telecom Bretagne (France), Team Ada. -- "Use the Source, Luke. The Source will be with you, always (GPL)." -- http://www-eleves.enst-bretagne.fr/~guerby/ (GATO Project). -- Try GNAT, the GNU Ada 95 compiler (ftp://cs.nyu.edu/pub/gnat). ^ permalink raw reply [flat|nested] 21+ messages in thread
* Re: Free'ing extended types 1996-04-29 0:00 ` Free'ing extended types Laurent Guerby @ 1996-04-29 0:00 ` Robert A Duff 0 siblings, 0 replies; 21+ messages in thread From: Robert A Duff @ 1996-04-29 0:00 UTC (permalink / raw) In article <4xrat6vlse.fsf@lagrange.enst-bretagne.fr>, Laurent Guerby <Laurent.Guerby@enst-bretagne.fr> wrote: > If another Ada compiler use different pools for the types in the >example, as permitted by the RM 13.11(17), then the execution of the >construct is erroneous. Then, of course, it can just work, don't work, >crash your disk or nicely dies with Program_Error ;-). Yes, but let's not get too alarmed, here. If "type Acc1 is access all T1'Class;" and "type Acc2 is access all T2'Class;", where T2 is a type extension of T1 (both tagged, of course), then we know (from accessibility rules) that these two are at the same nesting level, so I can't imagine any *reason* for the implementation to choose two different storage pools for Acc1 and Acc2. In retrospect, I admit we should have *required* Acc1 and Acc2 to share the same pool. But if no compiler writers show up saying they don't, why worry about it? (And if they do, perhaps the ARG ought to make a ruling on this point.) - Bob ^ permalink raw reply [flat|nested] 21+ messages in thread
end of thread, other threads:[~1996-05-24 0:00 UTC | newest] Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 1996-04-28 0:00 Free'ing extended types Jonas Nygren 1996-04-28 0:00 ` Robert Dewar 1996-04-29 0:00 ` Laurent Guerby 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Robert Dewar 1996-04-29 0:00 ` Jonas Nygren 1996-04-29 0:00 ` Robert A Duff 1996-04-29 0:00 ` Jonas Nygren 1996-04-29 0:00 ` Robert Dewar 1996-04-29 0:00 ` Robert A Duff 1996-05-20 0:00 ` Type conversion between access types (was: Free'ing extended types) Scott Leschke 1996-05-21 0:00 ` Dale Stanbrough 1996-05-21 0:00 ` Robert A Duff 1996-05-21 0:00 ` Robert A Duff 1996-05-22 0:00 ` Scott Leschke 1996-05-23 0:00 ` Robert A Duff 1996-05-23 0:00 ` progers 1996-05-24 0:00 ` Scott Leschke 1996-05-24 0:00 ` Robert A Duff 1996-04-29 0:00 ` Free'ing extended types Laurent Guerby 1996-04-29 0:00 ` Robert A Duff
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox