comp.lang.ada
 help / color / mirror / Atom feed
* Freeing Pointers to classwide types
@ 1998-09-24  0:00 joecool
  1998-09-25  0:00 ` alan walkington
                   ` (3 more replies)
  0 siblings, 4 replies; 61+ messages in thread
From: joecool @ 1998-09-24  0:00 UTC (permalink / raw)


Forgive me if this is an old question.  I am new to the group.

I am searching for information regarding the freeing of pointers to
classwide types.  I have been doing a great deal of searching on the web and
numerous texts.

Many texts discuss the use of pointers to classwide types for creating
heterogeneous arrays, buffers, etc. but darn little if nothing at all about
freeing the memory once you allocate it.

I understand (I think) how to dynamically allocate different objects within
a class and place them in a heterogenous list but I'm not sure if I
understand how to properly free the memory.

How do you go about freeing such critters?

Can anyone provide any background on this, or suggestions on where I can
find a detailed discussion of this topic?

Also, does anyone know of any problems in this area with the Aonix ObjectAda
compiler?  (This is NOT one of my favorite development environments!)

I would appreciate any assistance.







^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-24  0:00 Freeing Pointers to classwide types joecool
  1998-09-25  0:00 ` alan walkington
@ 1998-09-25  0:00 ` Tom Moran
  1998-09-25  0:00   ` Bob Fletcher
                     ` (2 more replies)
  1998-09-26  0:00 ` Simon Wright
  1998-10-09  0:00 ` Matthew Heaney
  3 siblings, 3 replies; 61+ messages in thread
From: Tom Moran @ 1998-09-25  0:00 UTC (permalink / raw)


>freeing the memory once you allocate it
Look up Unchecked_Deallocation in your Ada text if you are worried
about manually freeing memory, class-wide or not.   Of course one
would also hope
  procedure something(....) is
      type ptr is access ....
      p : ptr: := new ...
  ...
  end something
to free the memory pointed to by 'p' when it leaves procedure
something.      




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-24  0:00 Freeing Pointers to classwide types joecool
@ 1998-09-25  0:00 ` alan walkington
  1998-09-25  0:00 ` Tom Moran
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 61+ messages in thread
From: alan walkington @ 1998-09-25  0:00 UTC (permalink / raw)


If you are looking for the equivelent of an automatic 'destroy' function,
then
look up the 'ada.finalization.controlled' tagged type in any Ada95
reference.  Among other things, it will tell you how to set up a procedure
that is called whenever an instantiated object, derived from that class, is
destroyed.

Alan Walkington
walky@netmagic.net

joecool wrote in message <1ftmFTC69GA.191@samson.airnet.net>...
>Forgive me if this is an old question.  I am new to the group.

--- stuff deleted

>I understand (I think) how to dynamically allocate different objects within
>a class and place them in a heterogenous list but I'm not sure if I
>understand how to properly free the memory.
>
>How do you go about freeing such critters?
>








^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00 ` Tom Moran
@ 1998-09-25  0:00   ` Bob Fletcher
  1998-09-25  0:00     ` dennison
                       ` (2 more replies)
  1998-09-25  0:00   ` dewarr
  1998-10-09  0:00   ` Matthew Heaney
  2 siblings, 3 replies; 61+ messages in thread
From: Bob Fletcher @ 1998-09-25  0:00 UTC (permalink / raw)


Tom Moran <tmoran@bix.com> wrote in article
<360b26a1.41575272@SantaClara01.news.InterNex.Net>...
> Of course one
> would also hope
>   procedure something(....) is
>       type ptr is access ....
>       p : ptr: := new ...
>   ...
>   end something
> to free the memory pointed to by 'p' when it leaves procedure
> something.      

Really? Isn't the object that is created by the 'new' keyword similar in
nature to a C++ 'heap' variable, in that although the pointer may go out of
scope the object will not, and needs to be explicitly destroyed?
-- 
Bob Fletcher
Consultant, Logica UK

#ifndef STANDARD_DISCLAIMER_H
#define STANDARD_DISCLAIMER_H
{
   // All opinions are my own, not my employers'
}
#endif




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00   ` Bob Fletcher
  1998-09-25  0:00     ` dennison
@ 1998-09-25  0:00     ` Samuel Tardieu
  1998-10-09  0:00     ` Matthew Heaney
  2 siblings, 0 replies; 61+ messages in thread
From: Samuel Tardieu @ 1998-09-25  0:00 UTC (permalink / raw)


>>>>> "Bob" == Bob Fletcher <fletcherr@logica.com> writes:

Bob> Really? Isn't the object that is created by the 'new' keyword
Bob> similar in nature to a C++ 'heap' variable, in that although the
Bob> pointer may go out of scope the object will not, and needs to be
Bob> explicitly destroyed?

In this case, the pointer *type* goes out of scope, so unless your
object is a task or unless you're using Unchecked_Conversion to
another pointer type (or whatever), your objet (which is passive if it 
isn't a task) is not going to be accessed anymore (you can't affect it 
to an outer access type since it will have a smallest accessibility level).

Example:

| procedure Q is
| 
|    type String_Ptr_Almost_Global is access all String;
| 
|    T : String_Ptr_Almost_Global;
| 
| begin
|    declare
| 	type String_Ptr_Local is access all String;
| 	S : String_Ptr_Local;
|    begin
| 	S := new String'("abcde");
| 	T := String_Ptr_Almost_Global (S);
|    end;
| end Q;

Compiling this with GNAT will lead to:

    13.       T := String_Ptr_Almost_Global (S);
                                             |
        >>> cannot convert local pointer to non-local access type

  Sam
-- 
Samuel Tardieu -- sam@ada.eu.org




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00   ` Bob Fletcher
@ 1998-09-25  0:00     ` dennison
  1998-09-25  0:00     ` Samuel Tardieu
  1998-10-09  0:00     ` Matthew Heaney
  2 siblings, 0 replies; 61+ messages in thread
From: dennison @ 1998-09-25  0:00 UTC (permalink / raw)


In article <01bde866$1be8ed00$5330ea9e@UKP014459.logica.co.uk>,
  "Bob Fletcher" <fletcherr@logica.com> wrote:
> Tom Moran <tmoran@bix.com> wrote in article
> <360b26a1.41575272@SantaClara01.news.InterNex.Net>...
> > Of course one
> > would also hope
> >   procedure something(....) is
> >       type ptr is access ....
> >       p : ptr: := new ...
> >   ...
> >   end something
> > to free the memory pointed to by 'p' when it leaves procedure
> > something.
>
> Really? Isn't the object that is created by the 'new' keyword similar in
> nature to a C++ 'heap' variable, in that although the pointer may go out of
> scope the object will not, and needs to be explicitly destroyed?

Once the access *type* goes out of scope, any ptr variable you ever could have
assigned the pointer to (without using unchecked programming) is gone as well.
Ada compilers are free to deallocate the memory then.

How many of them actually *do* that, I'm not sure...

--
T.E.D.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00 ` Tom Moran
  1998-09-25  0:00   ` Bob Fletcher
@ 1998-09-25  0:00   ` dewarr
  1998-09-25  0:00     ` Tom Moran
  1998-09-26  0:00     ` Tom Moran
  1998-10-09  0:00   ` Matthew Heaney
  2 siblings, 2 replies; 61+ messages in thread
From: dewarr @ 1998-09-25  0:00 UTC (permalink / raw)


In article <360b26a1.41575272@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> >freeing the memory once you allocate it
> Look up Unchecked_Deallocation in your Ada text if you are worried
> about manually freeing memory, class-wide or not.   Of course one
> would also hope
>   procedure something(....) is
>       type ptr is access ....
>       p : ptr: := new ...
>   ...
>   end something
> to free the memory pointed to by 'p' when it leaves procedure
> something.

Tom, there is absolutely no reason to "hope" this, since it is certainly
not required semantics. On the contrary, it is clear that implementing such
semantics will require extra overhead, and it is far from clear that you want
this as the default behavior. In GNAT, we provide this behavior, but it is not
the default!

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00   ` dewarr
@ 1998-09-25  0:00     ` Tom Moran
  1998-09-25  0:00       ` dewarr
  1998-09-26  0:00     ` Tom Moran
  1 sibling, 1 reply; 61+ messages in thread
From: Tom Moran @ 1998-09-25  0:00 UTC (permalink / raw)


> no reason to "hope" this, since it is certainly
>not required
Oh, there are lots of things I "hope" that are not required.  I
"expect" that which is required. ;)




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00     ` Tom Moran
@ 1998-09-25  0:00       ` dewarr
  0 siblings, 0 replies; 61+ messages in thread
From: dewarr @ 1998-09-25  0:00 UTC (permalink / raw)


In article <360bd6fa.145464@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> > no reason to "hope" this, since it is certainly
> >not required
> Oh, there are lots of things I "hope" that are not required.  I
> "expect" that which is required. ;)


The point I was making is that really it is wrong to hope in this particular
case, since what you are hoping for is extra overhead (space and time
typically) which will for most programs buy you no advantage at all.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
@ 1998-09-25  0:00 bpr5549
  0 siblings, 0 replies; 61+ messages in thread
From: bpr5549 @ 1998-09-25  0:00 UTC (permalink / raw)


On Thu, 24 Sep 1998, joecool wrote:
> Forgive me if this is an old question.  I am new to the group.
>
> I am searching for information regarding the freeing of pointers to
> classwide types.  I have been doing a great deal of searching on the web and
> numerous texts.

In what way is the problem changed if you are not dealing with classwide
types, but just looking at the general problem of dynamic allocation? This
problem is not really language specific. The best reference I know of
(besides Knuth vol1 of course) is Paul Wilson's survey at

        http://www.cs.utexas.edu/users/oops/papers.html#allocsrv


> Many texts discuss the use of pointers to classwide types for creating
> heterogeneous arrays, buffers, etc. but darn little if nothing at all about
> freeing the memory once you allocate it.
>
> I understand (I think) how to dynamically allocate different objects within
> a class and place them in a heterogenous list but I'm not sure if I
> understand how to properly free the memory.
>
> How do you go about freeing such critters?

I assume that you know about Unchecked_Deallocation. Barnes second edition
also has some examples of how to write your own storage allocators.

Many of the programs I write are amenable to the strategy of deallocation
based on object lifetimes, i.e., you don't free individual objects but
free them in groups based on their lifetime. This technique is old, and
goes by many names; zones (1960s), arenas (Fraser & Hanson's lcc compiler),
and most recently regions (ML Kit). Ada programmers who've read the
Rationale know it as mark release storage, and the GNAT module s-secsta
is one implementation.

-- Brian

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-24  0:00 Freeing Pointers to classwide types joecool
  1998-09-25  0:00 ` alan walkington
  1998-09-25  0:00 ` Tom Moran
@ 1998-09-26  0:00 ` Simon Wright
  1998-10-09  0:00 ` Matthew Heaney
  3 siblings, 0 replies; 61+ messages in thread
From: Simon Wright @ 1998-09-26  0:00 UTC (permalink / raw)


If you have said

  type Event is <some tagged type>
  type Event_P is access Event'Class;

then you need to say

  procedure Delete is new Unchecked_Deallocation (Event'Class, Event_P);
                                                       ^^^^^^
because we have (from GNAT's source)

generic
   type Object (<>) is limited private;
   type Name is access Object;
procedure Unchecked_Deallocation (X : in out Name);

so you fill in the blanks from the declaration of type Event_P.

It took me ages to find this answer when I first had the problem!




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00   ` dewarr
  1998-09-25  0:00     ` Tom Moran
@ 1998-09-26  0:00     ` Tom Moran
  1998-09-26  0:00       ` dewarr
  1 sibling, 1 reply; 61+ messages in thread
From: Tom Moran @ 1998-09-26  0:00 UTC (permalink / raw)


>> to free the memory pointed to by 'p' when it leaves procedure
>> something.

>Tom, there is absolutely no reason to "hope" this, since it is certainly
>not required semantics

with Ada.Finalization;
package Test1 is
  type T is new Ada.Finalization.Controlled with null record;
  procedure Initialize(X : in out T);
  procedure Finalize(X : in out T);
end Test1;

with Ada.Text_IO;
package body Test1 is
  procedure Initialize(X : in out T) is
  begin
    Ada.Text_IO.Put_Line("Initialize");
  end Initialize;
  procedure Finalize(X : in out T) is
  begin
    Ada.Text_IO.Put_Line("Finalize");
  end Finalize;
end Test1;

with Test1,
     Ada.Text_IO;
procedure Test is
  procedure Something is
    type Ptr is access Test1.T;
    P : Ptr;
  begin
    Ada.Text_IO.Put_Line("start Something");
    P := new Test1.T;
    Ada.Text_IO.Put_Line("end Something");
  end Something;
begin
  Ada.Text_IO.Put_Line("Start");
  Something;
  Ada.Text_IO.Put_Line("End");
end Test;
                    The three compilers I tried all produce:
Start
start Something
Initialize
end Something
Finalize
End
     Do you mean that it would be legal Ada to produce a different
output, or that it should produce this  but might not actually free
the memory after the Finalize?





^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-26  0:00     ` Tom Moran
@ 1998-09-26  0:00       ` dewarr
  1998-09-26  0:00         ` Tom Moran
  0 siblings, 1 reply; 61+ messages in thread
From: dewarr @ 1998-09-26  0:00 UTC (permalink / raw)


In article <360c4a70.29707515@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:

<<code snipped>>


>      Do you mean that it would be legal Ada to produce a different
> output, or that it should produce this  but might not actually free
> the memory after the Finalize?


Absolutely, of course the finalize and initialize routines have to be
called as prescribed by the RM. But there is absolutely no suggestion
that some magic free operation would take place in your code. It *might*,
but then you could equally well say there *might* be complete automatic
garbage collection of either a conservative or full-tracing kind. Such
storage allocation schemes are *allowed* in Ada, but most certainly not
*required*.

In your code, the normal coding would be to do a free operation in the
finalization routine. In fact 99% of finalization routines do nothing
but explicit memory freeing in code that I have seen.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-26  0:00       ` dewarr
@ 1998-09-26  0:00         ` Tom Moran
  1998-09-27  0:00           ` dewarr
  1998-10-09  0:00           ` Matthew Heaney
  0 siblings, 2 replies; 61+ messages in thread
From: Tom Moran @ 1998-09-26  0:00 UTC (permalink / raw)


> the normal coding would be to do a free operation in the
>finalization routine
I'm unable to see a way to code such a finalization routine:
procedure Finalize(X : in out T) is
begin
   -- some code that frees the memory of X if it's on the heap 
   -- and nulls out the (any) pointer to X
end Finalize;




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-26  0:00         ` Tom Moran
@ 1998-09-27  0:00           ` dewarr
  1998-09-27  0:00             ` Tom Moran
  1998-10-09  0:00           ` Matthew Heaney
  1 sibling, 1 reply; 61+ messages in thread
From: dewarr @ 1998-09-27  0:00 UTC (permalink / raw)


In article <360d1380.165146@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> > the normal coding would be to do a free operation in the
> >finalization routine
> I'm unable to see a way to code such a finalization routine:
> procedure Finalize(X : in out T) is
> begin
>    -- some code that frees the memory of X if it's on the heap
>    -- and nulls out the (any) pointer to X
> end Finalize;


This can be done with access discriminants, but the most normal way of doing
things is to make the pointer finalizable. There are loads of examples of this
around in any text book, or in the GNAT library or anywhere else you look.


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-27  0:00           ` dewarr
@ 1998-09-27  0:00             ` Tom Moran
  1998-09-28  0:00               ` dewarr
  0 siblings, 1 reply; 61+ messages in thread
From: Tom Moran @ 1998-09-27  0:00 UTC (permalink / raw)


>This can be done with access discriminants, but the most normal way of doing
>things is to make the pointer finalizable.
Neither of which works in the case under discussion, where the access
type was declared inside a procedure and thus after the (global) type
definition.
  I quite agree that Ada is a powerful language in which you can find
a way to do almost anything - but sometimes it takes a substantial
change in the design ( "make the pointer finalizable") to accomplish
the goal.  It's usually also true that a new design is in fact much
better than the one that painted you into a corner.  But in this case
it seems to me you are saying "do a big redesign, possibly affecting
any package that uses this type, in which a bunch of stuff is made
global and complex, instead of local and straightforward, or take the
risk of a major storage leak, or use unchecked programming".  It might
even make a person include "no storage leak in this case" as a
criterion in choosing one compiler over another.  You say it's
expensive to not have a storage leak in this case.  Why?  Do there
exist compilers that do leak?  You've said Gnat doesn't leak - are
there plans to change that?
 




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-27  0:00             ` Tom Moran
@ 1998-09-28  0:00               ` dewarr
  1998-09-28  0:00                 ` Tom Moran
  0 siblings, 1 reply; 61+ messages in thread
From: dewarr @ 1998-09-28  0:00 UTC (permalink / raw)


In article <360e790d.241368@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> >This can be done with access discriminants, but the most normal way of doing
> >things is to make the pointer finalizable.
> Neither of which works in the case under discussion, where the access
> type was declared inside a procedure and thus after the (global) type
> definition.
>   I quite agree that Ada is a powerful language in which you can find
> a way to do almost anything - but sometimes it takes a substantial
> change in the design ( "make the pointer finalizable") to accomplish
> the goal.  It's usually also true that a new design is in fact much
> better than the one that painted you into a corner.  But in this case
> it seems to me you are saying "do a big redesign, possibly affecting
> any package that uses this type, in which a bunch of stuff is made
> global and complex, instead of local and straightforward, or take the
> risk of a major storage leak, or use unchecked programming".  It might
> even make a person include "no storage leak in this case" as a
> criterion in choosing one compiler over another.  You say it's
> expensive to not have a storage leak in this case.  Why?  Do there
> exist compilers that do leak?  You've said Gnat doesn't leak - are
> there plans to change that?


No, there are no plans to change the *default* but as I have said before,
GNAT provides a choice in this respect. Consult the GNAT documentation for
details!

Any code that *assumes* this kind of automatic collection is badly flawed
and non-portable. As always, most portability problems in Ada are caused
by incompetent programming.

As for major redesign, no, that's not required, it is actually quite easy
in Ada 95 to do exactly what you want. You probably aren't familiar with
the Storage_Pool facility -- many Ada programmers don't know this very
powerful feature in the language well enough, but read up on it, you will
find it allows you to do exactly what you want in a completely portable
manner.

By the way, relatively few compilers have done this kind of automatic
free operation, so it is fairly rare to find code that makes the mistake
of assuming that this is done.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00               ` dewarr
@ 1998-09-28  0:00                 ` Tom Moran
  1998-09-28  0:00                   ` dewarr
  1998-09-28  0:00                   ` dewarr
  0 siblings, 2 replies; 61+ messages in thread
From: Tom Moran @ 1998-09-28  0:00 UTC (permalink / raw)


> it is actually quite easy
>in Ada 95 to do exactly what you want. You probably aren't familiar with
>the Storage_Pool facility -- many Ada programmers don't know this very
>powerful feature in the language well enough, but read up on it, you will
>find it allows you to do exactly what you want in a completely portable
>manner.
Deciding to use Storage Pools does not fall within my definition of
modest changes to a program.
  In any case, is it required that a compiler that does not free
memory when an access type goes out of scope, must free the memory if
the access type is to a user controlled storage pool?  That's not
obvious to me from reading the RM.  Or would the procedure declaring
the access type also have to declare an instance of the user defined
storage pool?  And if the reason not to use a compiler that frees the
storage is that it's expensive, is the user defined storage pool
technique cheap?




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                 ` Tom Moran
  1998-09-28  0:00                   ` dewarr
@ 1998-09-28  0:00                   ` dewarr
  1998-09-28  0:00                     ` Richard D Riehle
  1 sibling, 1 reply; 61+ messages in thread
From: dewarr @ 1998-09-28  0:00 UTC (permalink / raw)


In article <360f143c.39974468@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> > it is actually quite easy
> >in Ada 95 to do exactly what you want. You probably aren't familiar with
> >the Storage_Pool facility -- many Ada programmers don't know this very
> >powerful feature in the language well enough, but read up on it, you will
> >find it allows you to do exactly what you want in a completely portable
> >manner.
> Deciding to use Storage Pools does not fall within my definition of
> modest changes to a program.
>   In any case, is it required that a compiler that does not free
> memory when an access type goes out of scope, must free the memory if
> the access type is to a user controlled storage pool?  That's not
> obvious to me from reading the RM.  Or would the procedure declaring
> the access type also have to declare an instance of the user defined
> storage pool?  And if the reason not to use a compiler that frees the
> storage is that it's expensive, is the user defined storage pool
> technique cheap?


You really should look at the Storage_Pools facility. You seem to be declaring
that you are sure it is not a modest change, but then ask questions that
suggest you are not quite sure what such a change would involve. In the case
of GNAT, it is just a matter of adding a single representation clause for the
type, not a big burden.

The point about using Storage_Pool's is not that it eliminates the overhead,
of course it does not, since there is no magic way of doing this, but that
you only pay this overhead if you want.

I find nothing in what you are saying that would seem to justify adding this
additional overhead unconditionally. Indeed, the less magic going on the
better as far as I am concerned.

Once again, the expectation here that a compiler will free all storage
associated with local allocators on scope exit is not justified. It is
no more or less justified than expecting that you will find a complete
garbage collector (after all this is just a special case of automatic
garbage collection, why single it out?)


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                 ` Tom Moran
@ 1998-09-28  0:00                   ` dewarr
  1998-09-28  0:00                     ` Tom Moran
  1998-09-28  0:00                   ` dewarr
  1 sibling, 1 reply; 61+ messages in thread
From: dewarr @ 1998-09-28  0:00 UTC (permalink / raw)


In article <360f143c.39974468@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
>   In any case, is it required that a compiler that does not free
> memory when an access type goes out of scope, must free the memory if
> the access type is to a user controlled storage pool?  That's not
> obvious to me from reading the RM.

Just to answer this question, no of course not. The whole point of a
user storage pool is that the user defines what is to be done! In the case
of GNAT, the library contains prebuilt versions of the implementations
that are required.


-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                   ` dewarr
@ 1998-09-28  0:00                     ` Tom Moran
  1998-09-28  0:00                       ` Pat Rogers
  1998-09-28  0:00                       ` Tom Moran
  0 siblings, 2 replies; 61+ messages in thread
From: Tom Moran @ 1998-09-28  0:00 UTC (permalink / raw)


>The whole point of a
>user storage pool is that the user defines what is to be done!
My understanding of the RM is that a user decides how the Allocate and
Deallocate procedures for his storage pool will work.  The question at
issue, however, is when Deallocate is to be called.  How does the user
specify this?
  If the user specifies a private storage pool inside the procedure,
eg
      procedure Something is
         My_Pool : My_Pool_Type(5000);
then, hopefully(is this required?), the compiler will release the
storage of My_Pool on scope exit, thus effectively releasing the
memory of any access types going out of scope that are associated with
My_Pool.  Is that the only way to prevent the storage leak?  It
certainly seems to me that having a bunch of small storage pools in a
program, instead of one large shared heap, obviates one of the reasons
for using heap storage as opposed to simply declaring, say, a
plenty-large array of elements of the relevant type and using inexing
instead of access types.
  I tested the original code I posted in this thread to see what Gnat
3.11 does on exiting the scope of an access type.  The answer is that
multiple calls to the procedure will result in a Storage Error.  The
gnat-rm.txt file says to look in s-gnapoo (which I don't have handy)
for what is presumably a vendor-supplied-library storage pool.  Is
that what you mean by how trivial it is to use storage pools in Gnat?
Without this, the user would have to write his own Allocate and
Deallocate, which, frankly, I would hope, but not expect, all
programmers to do well. 
   So it appears to me the bottom line is:If you want to release the
memory on procedure exit, you will have to do stack-like, rather than
heap-like allocation of an instance of a special storage pool.  Your
compiler vendor may, or may not, offer helpful, well written, storage
pool routines as part of his vendor-supplied-library.  Am I mistaken?




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                     ` Richard D Riehle
@ 1998-09-28  0:00                       ` Pat Rogers
  1998-09-29  0:00                       ` dewarr
  1 sibling, 0 replies; 61+ messages in thread
From: Pat Rogers @ 1998-09-28  0:00 UTC (permalink / raw)


Richard D Riehle wrote in message
<6uojcq$bp2@sjx-ixn3.ix.netcom.com>...
>In article <6uo83j$dv2$1@nnrp1.dejanews.com>,
> dewarr@my-dejanews.com wrote:
>
>In reply to a question from Tom Moran about System.Storage_Pools
(ALRM
>13.11),
>
>>You really should look at the Storage_Pools facility. You seem to
be
>declaring
>>that you are sure it is not a modest change, but then ask
questions that
>>suggest you are not quite sure what such a change would involve.
In the
>case
>>of GNAT, it is just a matter of adding a single representation
clause for
>the
>>type, not a big burden.
>
>I checked the GNAT documentation. Am I missing something, I wonder?
Does
>GNAT already include an overloading of the subprograms in
>System.Storage_Pool.  If so, Robert's assertion that "it is just a
matter of
>adding a single representation clause" might be sufficient.
Otherwise, it
>is a bit misleading in its suggestion of simplicity.

Given the declaration of a pool, all that is required is for the
user to do as Robert says.  The hard part is writing the extension
of Ada.System.Storage_Pools for use in declaraing the pool, and I
gather than GNAT has done this.

>There are very few examples in the literature for using
>System.Storage_Pools.  At several Ada conferences I asked prominent
>technical experts if they could point me to some references where
someone
>had actually implemented an overloading  of System.Storage_Pools.
None of
>those I asked were forthcoming.  The example in the Rationale falls
into the
>category of "seduced and abandoned."

One of the things I've been teaching for the last few years in my
Real-Time class is how to do this, and I show in detail how to write
a deterministic fixed-block pool manager since there are so few
examples around.  I have this little saying I give after the
schedulability analysis chapter: "If you don't take responsbility
for storage management, you'll run out of storage right on
schedule."

In an upcomng release of the Booch Components, you will see an
example of a general purpose ("Managed") allocator that I wrote
based directly on Grady's C++ version.








^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                     ` Tom Moran
@ 1998-09-28  0:00                       ` Pat Rogers
  1998-09-28  0:00                         ` Tom Moran
  1998-09-28  0:00                       ` Tom Moran
  1 sibling, 1 reply; 61+ messages in thread
From: Pat Rogers @ 1998-09-28  0:00 UTC (permalink / raw)


Tom Moran wrote in message
<360fc072.1728326@SantaClara01.news.InterNex.Net>...
>>The whole point of a
>>user storage pool is that the user defines what is to be done!
>My understanding of the RM is that a user decides how the Allocate
and
>Deallocate procedures for his storage pool will work.  The question
at
>issue, however, is when Deallocate is to be called.  How does the
user
>specify this?

The system calls Deallocate for you whenever an object ceases to
exist for declared objects or an instance of unchecked deallocation
is called for allocated objects.

>  If the user specifies a private storage pool inside the
procedure,
>eg
>      procedure Something is
>         My_Pool : My_Pool_Type(5000);
>then, hopefully(is this required?), the compiler will release the
>storage of My_Pool on scope exit, thus effectively releasing the
>memory of any access types going out of scope that are associated
with
>My_Pool.  Is that the only way to prevent the storage leak?

If the storage is completely represented by My_Pool, then yes, that
is all that is required.  In a fixed-block allocator, for example,
My_Pool_Type would contain everything necessary to represent and
manage the pool.  In a more general purpose version, My_Pool_Type
would contain mostly pointers to allocated objects, from whence the
allocated application values would come, and Finalize for
My_Pool_Type would do the reclamation.  In concept neither is too
difficult, but the devil is certainly in the details (i.e., watch
that alignment!).


-- pat

Patrick Rogers
progers@acm.org
http://www.neosoft.com/~progers






^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                     ` Tom Moran
  1998-09-28  0:00                       ` Pat Rogers
@ 1998-09-28  0:00                       ` Tom Moran
  1998-09-28  0:00                         ` Brian Rogoff
  1 sibling, 1 reply; 61+ messages in thread
From: Tom Moran @ 1998-09-28  0:00 UTC (permalink / raw)


Oops, I left out of 'the bottom line' the possibility of adding
set_mark/release_to_mark procedures to the storage pool, a la the
Rationale example.  Does the Gnat vendor-supplied version have those?




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                       ` Pat Rogers
@ 1998-09-28  0:00                         ` Tom Moran
  1998-09-28  0:00                           ` Pat Rogers
  1998-09-29  0:00                           ` dewarr
  0 siblings, 2 replies; 61+ messages in thread
From: Tom Moran @ 1998-09-28  0:00 UTC (permalink / raw)


>The system calls Deallocate for you whenever an object ceases to
>exist for declared objects or an instance of unchecked deallocation
>is called for allocated objects.
Does the system call Deallocate for you when, as in the case under
discussion, the access *type* goes out of scope (and thus ceases to
exist and thus anything it pointed to becomes inaccessible)?




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                         ` Tom Moran
@ 1998-09-28  0:00                           ` Pat Rogers
  1998-09-29  0:00                           ` dewarr
  1 sibling, 0 replies; 61+ messages in thread
From: Pat Rogers @ 1998-09-28  0:00 UTC (permalink / raw)


Tom Moran wrote in message
<360fec6e.12989714@SantaClara01.news.InterNex.Net>...
>>The system calls Deallocate for you whenever an object ceases to
>>exist for declared objects or an instance of unchecked
deallocation
>>is called for allocated objects.
>Does the system call Deallocate for you when, as in the case under
>discussion, the access *type* goes out of scope (and thus ceases to
>exist and thus anything it pointed to becomes inaccessible)?

That is a separate issue.






^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                       ` Tom Moran
@ 1998-09-28  0:00                         ` Brian Rogoff
  0 siblings, 0 replies; 61+ messages in thread
From: Brian Rogoff @ 1998-09-28  0:00 UTC (permalink / raw)


Tom,
	If you have GNAT source at hand look at s-secsta.ad{sb}, that
implements a mark/release pool, or "region based allocator" if you want 
to publish papers in SIGPLAN :-)

	I'm working on a few allocators, including a region based one, 
which will go in some future release of my generic library. 

-- Brian

On Mon, 28 Sep 1998, Tom Moran wrote:

> Oops, I left out of 'the bottom line' the possibility of adding
> set_mark/release_to_mark procedures to the storage pool, a la the
> Rationale example.  Does the Gnat vendor-supplied version have those?
> 
> 





^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                   ` dewarr
@ 1998-09-28  0:00                     ` Richard D Riehle
  1998-09-28  0:00                       ` Pat Rogers
  1998-09-29  0:00                       ` dewarr
  0 siblings, 2 replies; 61+ messages in thread
From: Richard D Riehle @ 1998-09-28  0:00 UTC (permalink / raw)


In article <6uo83j$dv2$1@nnrp1.dejanews.com>,
	dewarr@my-dejanews.com wrote:

In reply to a question from Tom Moran about System.Storage_Pools (ALRM
13.11),

>You really should look at the Storage_Pools facility. You seem to be
declaring
>that you are sure it is not a modest change, but then ask questions that
>suggest you are not quite sure what such a change would involve. In the
case
>of GNAT, it is just a matter of adding a single representation clause for
the
>type, not a big burden.

I checked the GNAT documentation. Am I missing something, I wonder?  Does
GNAT already include an overloading of the subprograms in
System.Storage_Pool.  If so, Robert's assertion that "it is just a matter of
adding a single representation clause" might be sufficient.  Otherwise, it
is a bit misleading in its suggestion of simplicity.

The representation clause is only a small part of the requirement for
using the abstract class package System.Storage_Pools.  One must also
overload the Allocate and Deallocate procedures.  In fact, to make this
package really useful, one must also overload the initialize and finalize
procedures from Ada.Finalization.  

There are very few examples in the literature for using 
System.Storage_Pools.  At several Ada conferences I asked prominent
technical experts if they could point me to some references where someone
had actually implemented an overloading  of System.Storage_Pools.  None of
those I asked were forthcoming.  The example in the Rationale falls into the
category of "seduced and abandoned."

More recently, John Barnes, dependable Ada stalwart, included an excellent
example in the Second Edition of his book, Programming in Ada 95.  It is
fully coded, readable, and enlightening.  However, it is clear from studying
the Barnes example that System.Storage_Pools is, in practice, a non-trivial
issue.   

Richard Riehle
richard@adaworks.com
http://www.adaworks.com


 




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                     ` Richard D Riehle
  1998-09-28  0:00                       ` Pat Rogers
@ 1998-09-29  0:00                       ` dewarr
  1 sibling, 0 replies; 61+ messages in thread
From: dewarr @ 1998-09-29  0:00 UTC (permalink / raw)


In article <6uojcq$bp2@sjx-ixn3.ix.netcom.com>,
  Richard D Riehle <laoxhai@ix.netcom.com> wrote:

> I checked the GNAT documentation. Am I missing something, I wonder?  Does
> GNAT already include an overloading of the subprograms in
> System.Storage_Pool.  If so, Robert's assertion that "it is just a matter of
> adding a single representation clause" might be sufficient.  Otherwise, it
> is a bit misleading in its suggestion of simplicity.

Indeed GNAT does supply some standard implementations for storage pools,
and one of them is exactly the one that is needed for automatic freeing
of storage on scope exit.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-28  0:00                         ` Tom Moran
  1998-09-28  0:00                           ` Pat Rogers
@ 1998-09-29  0:00                           ` dewarr
  1998-09-29  0:00                             ` Tom Moran
  1 sibling, 1 reply; 61+ messages in thread
From: dewarr @ 1998-09-29  0:00 UTC (permalink / raw)


In article <360fec6e.12989714@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> >The system calls Deallocate for you whenever an object ceases to
> >exist for declared objects or an instance of unchecked deallocation
> >is called for allocated objects.
> Does the system call Deallocate for you when, as in the case under
> discussion, the access *type* goes out of scope (and thus ceases to
> exist and thus anything it pointed to becomes inaccessible)?

Tom, the implementation is fairly straightforward, it uses a controlled type
to ensure that the storage is released on scope exit. If you don't see how
to do this, just look at the coding in the GNAT library.

-----== Posted via Deja News, The Leader in Internet Discussion ==-----
http://www.dejanews.com/rg_mkgrp.xp   Create Your Own Free Member Forum




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-29  0:00                           ` dewarr
@ 1998-09-29  0:00                             ` Tom Moran
  1998-09-30  0:00                               ` Tom Moran
  0 siblings, 1 reply; 61+ messages in thread
From: Tom Moran @ 1998-09-29  0:00 UTC (permalink / raw)


> just look at the coding in the GNAT library.
Ah, I see.  s-pooloc just overrides Allocate and Deallocate so it can
keep track of the allocations/deallocations, so Finalize can free
things.  The actual storage allocation is still done from the original
heap by the original allocator.  Yes, even a mediocre programmer
should be able to do that without danger.  I thought you were
suggesting that he whip up his own storage allocator.




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-29  0:00                             ` Tom Moran
@ 1998-09-30  0:00                               ` Tom Moran
  1998-10-01  0:00                                 ` dewar
  0 siblings, 1 reply; 61+ messages in thread
From: Tom Moran @ 1998-09-30  0:00 UTC (permalink / raw)


>actual storage allocation is still done from the original
>heap by the original allocator
  This, of course, is a direct call to the vendor supplied RTS and
thus is not at all portable.




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-30  0:00                               ` Tom Moran
@ 1998-10-01  0:00                                 ` dewar
  1998-10-01  0:00                                   ` Tom Moran
  0 siblings, 1 reply; 61+ messages in thread
From: dewar @ 1998-10-01  0:00 UTC (permalink / raw)


In article <36127a1c.276097@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> >actual storage allocation is still done from the original
> >heap by the original allocator
>   This, of course, is a direct call to the vendor supplied RTS and
> thus is not at all portable.

There is no "of course" here. The GNAT implementation happens to call the
underlying allocation routine in the RTS directly because this is more
straightforward, and there is no attempt to make GNAT runtime routines
portable to non-GNAT Ada compilers.

But it is a trivial excercise to rewrite this so that it uses an Ada
allocator instead of the direct call if you want to be completely portable.


Robert Dewar
Ada Core Technologies

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                 ` dewar
@ 1998-10-01  0:00                                   ` Tom Moran
  1998-10-01  0:00                                     ` dewarr
                                                       ` (2 more replies)
  0 siblings, 3 replies; 61+ messages in thread
From: Tom Moran @ 1998-10-01  0:00 UTC (permalink / raw)


>But it is a trivial excercise to rewrite this so that it uses an Ada
>allocator
Without using Unchecked_Conversion and Unchecked_Deallocation?




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                   ` Tom Moran
  1998-10-01  0:00                                     ` dewarr
  1998-10-01  0:00                                     ` dewarr
@ 1998-10-01  0:00                                     ` Samuel Tardieu
  1998-10-01  0:00                                       ` Tom Moran
  2 siblings, 1 reply; 61+ messages in thread
From: Samuel Tardieu @ 1998-10-01  0:00 UTC (permalink / raw)


>>>>> "Tom" == Tom Moran <tmoran@bix.com> writes:

Tom> Without using Unchecked_Conversion

Easy.

Tom> and Unchecked_Deallocation?

Depends whether you want to reuse allocated-then-freed memory or not.

  Sam
-- 
Samuel Tardieu -- sam@ada.eu.org




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                   ` Tom Moran
@ 1998-10-01  0:00                                     ` dewarr
  1998-10-01  0:00                                     ` dewarr
  1998-10-01  0:00                                     ` Samuel Tardieu
  2 siblings, 0 replies; 61+ messages in thread
From: dewarr @ 1998-10-01  0:00 UTC (permalink / raw)


In article <36131a1b.34896409@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> >But it is a trivial excercise to rewrite this so that it uses an Ada
> >allocator
> Without using Unchecked_Conversion and Unchecked_Deallocation?

And why on earth would you try to avoid these? You can write perfectly
portable code using these routines if you know what you are doing. It
is particularly odd to complain about the use of Unchecked_Deallocation
in a routine devoted to storage allocation and deallocation, and there
is nothing at all non-portable about the kind of use of UD you would
use here. As for UC, sure you have to be careful how you use it, and
from a formal point of view, it is probably true that the RM will not
guarantee that what you would write would work, but that should not
deter you from writing perfectly portable code (in practice) using UC.

It is always surprising when people are absolutely set against UC, and
the result is that people write code in C that is exactly equivalent.

I remember one comparison of Ada vs C presentation I saw for an AI
application. The C was much faster. Virtually 100% of the difference
was in allocation. I asked what was going on

"Do you use malloc?"

"Oh no, that's far too slow, we wrote our own allocator in C"

"Well why didn't you do the same in Ada"

"Because it wouldn't have been portable"

"But your C is not portable in a formal sense anyway"

"Well it works on three different machines!!!"

Sigh!

Ada folks are good at shooting themselves in the foot, and it isn't even
the language that's doing it :-)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                   ` Tom Moran
  1998-10-01  0:00                                     ` dewarr
@ 1998-10-01  0:00                                     ` dewarr
  1998-10-01  0:00                                       ` Tom Moran
  1998-10-01  0:00                                     ` Samuel Tardieu
  2 siblings, 1 reply; 61+ messages in thread
From: dewarr @ 1998-10-01  0:00 UTC (permalink / raw)


In article <36131a1b.34896409@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> >But it is a trivial excercise to rewrite this so that it uses an Ada
> >allocator
> Without using Unchecked_Conversion and Unchecked_Deallocation?


Actually more accurately you would not use Unchecked_Conversion but
System.Address_To_Access_Conversions, there does that make you feel better?

If even that is ruled out for some odd reason, you could actually manage
just with the 'Address attribute and address aritmetic available in
System.Storage_Elements.

If you are ruling even that out, then you are intent not just on shooting
yourself in the foot, but in the head :-)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                     ` Samuel Tardieu
@ 1998-10-01  0:00                                       ` Tom Moran
  1998-10-01  0:00                                         ` dennison
                                                           ` (2 more replies)
  0 siblings, 3 replies; 61+ messages in thread
From: Tom Moran @ 1998-10-01  0:00 UTC (permalink / raw)


>Tom> and Unchecked_Deallocation?

>Depends whether you want to reuse allocated-then-freed memory or not.
  Since this section of the thread started with a discussion of
automatic, ie, not via Unchecked_Deallocation, of memory, it would
seem strange to me to go to all this trouble just to wind up using
Unchecked_Deallocation after all.  And since the whole discussion is
about what to do if your compiler doesn't free, ie, make available for
re-use, certain memory automatically, "free"ing, but not making
available for re-use, also doesn't seem useful.   
  Let me rephrase the question: If an access type goes out of scope,
so the things it pointed to become inaccessible, is there any portable
way to prevent an eventual Storage_Error from multiple calls of the
block, without using Unchecked_Deallocation?    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                     ` dewarr
@ 1998-10-01  0:00                                       ` Tom Moran
  0 siblings, 0 replies; 61+ messages in thread
From: Tom Moran @ 1998-10-01  0:00 UTC (permalink / raw)


We'll just have to agree to disagree on the meaning of "trivial".




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                       ` Tom Moran
@ 1998-10-01  0:00                                         ` dennison
  1998-10-01  0:00                                         ` Tucker Taft
  1998-10-02  0:00                                         ` dewarr
  2 siblings, 0 replies; 61+ messages in thread
From: dennison @ 1998-10-01  0:00 UTC (permalink / raw)


In article <3613a5b1.186262@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
>   Let me rephrase the question: If an access type goes out of scope,
> so the things it pointed to become inaccessible, is there any portable
> way to prevent an eventual Storage_Error from multiple calls of the
> block, without using Unchecked_Deallocation?

I suppose you could use custom storage pools to create you own heap using
arrays. I'm a little unclear as to why that would be better than
Unchecked_Deallocation, though.

I you are aksing if there is a portable way to deallocate memory without
dealloacting the memory, I'm afraid the answer is no.


--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                       ` Tom Moran
  1998-10-01  0:00                                         ` dennison
@ 1998-10-01  0:00                                         ` Tucker Taft
  1998-10-01  0:00                                           ` Tom Moran
                                                             ` (2 more replies)
  1998-10-02  0:00                                         ` dewarr
  2 siblings, 3 replies; 61+ messages in thread
From: Tucker Taft @ 1998-10-01  0:00 UTC (permalink / raw)


Tom Moran (tmoran@bix.com) wrote:

: ...
:   Let me rephrase the question: If an access type goes out of scope,
: so the things it pointed to become inaccessible, is there any portable
: way to prevent an eventual Storage_Error from multiple calls of the
: block, without using Unchecked_Deallocation?    

Yes.  Specify the 'Storage_Size associated with the access-type.
The implementation is required to reclaim the storage for the
access type when exiting its scope if a 'Storage_Size is specified
(see RM95 13.11(18)).

--
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA
An AverStar Company




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                         ` Tucker Taft
@ 1998-10-01  0:00                                           ` Tom Moran
  1998-10-02  0:00                                           ` dewarr
  1998-10-02  0:00                                           ` dennison
  2 siblings, 0 replies; 61+ messages in thread
From: Tom Moran @ 1998-10-01  0:00 UTC (permalink / raw)


>Yes.  Specify the 'Storage_Size associated with the access-type.
>The implementation is required to reclaim the storage for the
>access type when exiting its scope if a 'Storage_Size is specified
>(see RM95 13.11(18)).
Excellent!




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-02  0:00                                           ` dennison
@ 1998-10-02  0:00                                             ` dewarr
  0 siblings, 0 replies; 61+ messages in thread
From: dewarr @ 1998-10-02  0:00 UTC (permalink / raw)


In article <6v2s7t$eq0$1@nnrp1.dejanews.com>,
  dennison@telepath.com wrote:
> In article <F05vr9.HLv.0.-s@inmet.camb.inmet.com>,
>   stt@houdini.camb.inmet.com (Tucker Taft) wrote:
>
> > Yes.  Specify the 'Storage_Size associated with the access-type.
> > The implementation is required to reclaim the storage for the
> > access type when exiting its scope if a 'Storage_Size is specified
> > (see RM95 13.11(18)).
>
> Cool! I suppose that could lead to STORAGE_ERRORs when the code is modified,
> though. That seems a reasonable trade-off


This is a feature that has always been in Ada, and of course is the proper
diction to use if you can establish a reasonable upper bound for the size
of the collection. I was assuming in the earlier discussions that this was
not the case, but as long as it is, things are straightforward indeed!


-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-02  0:00                                             ` Larry Kilgallen
@ 1998-10-02  0:00                                               ` dewarr
  0 siblings, 0 replies; 61+ messages in thread
From: dewarr @ 1998-10-02  0:00 UTC (permalink / raw)


In article <1998Oct2.123113.1@eisner>,
  Kilgallen@eisner.decus.org.nospam wrote:
> In article <6v15di$87t$1@nnrp1.dejanews.com>, dewarr@my-dejanews.com writes:
> > In article <F05vr9.HLv.0.-s@inmet.camb.inmet.com>,
> >   stt@houdini.camb.inmet.com (Tucker Taft) wrote:
> >> Tom Moran (tmoran@bix.com) wrote:
> >>
> >> : ...
> >> :   Let me rephrase the question: If an access type goes out of scope,
> >> : so the things it pointed to become inaccessible, is there any portable
> >> : way to prevent an eventual Storage_Error from multiple calls of the
> >> : block, without using Unchecked_Deallocation?
> >>
> >> Yes.  Specify the 'Storage_Size associated with the access-type.
> >> The implementation is required to reclaim the storage for the
> >> access type when exiting its scope if a 'Storage_Size is specified
> >> (see RM95 13.11(18)).
> >
> >
> > Yes, indeed! Nice answer, but I was assuming that this obvious approach of
> > fixed size allocation was not acceptable, in which case you are definitely
> > going to have to use UD I am afraid :-)
>
> Is it common for implementations to allocate the maximum size when the
> type is elaborated ?  I had presumed the maximum would just be a limit
> beyond which the total of one-at-a-time allocations would not proceed.
> In that case I figured from the discussion that setting Storage_Size
> to MAX_INT (never intending to get there) would accomplish the deallocation
> purpose.
>
> Larry Kilgallen

Yes absolutely, allocating the maximum immediately as a single area on the
stack is the expected and usual implementation.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                       ` Tom Moran
  1998-10-01  0:00                                         ` dennison
  1998-10-01  0:00                                         ` Tucker Taft
@ 1998-10-02  0:00                                         ` dewarr
  1998-10-09  0:00                                           ` Matthew Heaney
  2 siblings, 1 reply; 61+ messages in thread
From: dewarr @ 1998-10-02  0:00 UTC (permalink / raw)


In article <3613a5b1.186262@SantaClara01.news.InterNex.Net>,
  tmoran@bix.com (Tom Moran) wrote:
> >Tom> and Unchecked_Deallocation?
>
> >Depends whether you want to reuse allocated-then-freed memory or not.
>   Since this section of the thread started with a discussion of
> automatic, ie, not via Unchecked_Deallocation, of memory, it would
> seem strange to me to go to all this trouble just to wind up using
> Unchecked_Deallocation after all.  And since the whole discussion is
> about what to do if your compiler doesn't free, ie, make available for
> re-use, certain memory automatically, "free"ing, but not making
> available for re-use, also doesn't seem useful.
>   Let me rephrase the question: If an access type goes out of scope,
> so the things it pointed to become inaccessible, is there any portable
> way to prevent an eventual Storage_Error from multiple calls of the
> block, without using Unchecked_Deallocation?


The answer is no, but so what? This is like asking if there is a way to
define a function without using the function keyword, or whether there is
a way to have concurrent execution without using the task keyword.
Unchecked_Deallocation is for use in such contexts, why on earth worry
about whether you can do unchecked deallocations without using
Unchecked_Deallocation?

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                         ` Tucker Taft
  1998-10-01  0:00                                           ` Tom Moran
@ 1998-10-02  0:00                                           ` dewarr
  1998-10-02  0:00                                             ` Larry Kilgallen
  1998-10-02  0:00                                           ` dennison
  2 siblings, 1 reply; 61+ messages in thread
From: dewarr @ 1998-10-02  0:00 UTC (permalink / raw)


In article <F05vr9.HLv.0.-s@inmet.camb.inmet.com>,
  stt@houdini.camb.inmet.com (Tucker Taft) wrote:
> Tom Moran (tmoran@bix.com) wrote:
>
> : ...
> :   Let me rephrase the question: If an access type goes out of scope,
> : so the things it pointed to become inaccessible, is there any portable
> : way to prevent an eventual Storage_Error from multiple calls of the
> : block, without using Unchecked_Deallocation?
>
> Yes.  Specify the 'Storage_Size associated with the access-type.
> The implementation is required to reclaim the storage for the
> access type when exiting its scope if a 'Storage_Size is specified
> (see RM95 13.11(18)).


Yes, indeed! Nice answer, but I was assuming that this obvious approach of
fixed size allocation was not acceptable, in which case you are definitely
going to have to use UD I am afraid :-)

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-01  0:00                                         ` Tucker Taft
  1998-10-01  0:00                                           ` Tom Moran
  1998-10-02  0:00                                           ` dewarr
@ 1998-10-02  0:00                                           ` dennison
  1998-10-02  0:00                                             ` dewarr
  2 siblings, 1 reply; 61+ messages in thread
From: dennison @ 1998-10-02  0:00 UTC (permalink / raw)


In article <F05vr9.HLv.0.-s@inmet.camb.inmet.com>,
  stt@houdini.camb.inmet.com (Tucker Taft) wrote:

> Yes.  Specify the 'Storage_Size associated with the access-type.
> The implementation is required to reclaim the storage for the
> access type when exiting its scope if a 'Storage_Size is specified
> (see RM95 13.11(18)).

Cool! I suppose that could lead to STORAGE_ERRORs when the code is modified,
though. That seems a reasonable trade-off.


--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-02  0:00                                           ` dewarr
@ 1998-10-02  0:00                                             ` Larry Kilgallen
  1998-10-02  0:00                                               ` dewarr
  0 siblings, 1 reply; 61+ messages in thread
From: Larry Kilgallen @ 1998-10-02  0:00 UTC (permalink / raw)


In article <6v15di$87t$1@nnrp1.dejanews.com>, dewarr@my-dejanews.com writes:
> In article <F05vr9.HLv.0.-s@inmet.camb.inmet.com>,
>   stt@houdini.camb.inmet.com (Tucker Taft) wrote:
>> Tom Moran (tmoran@bix.com) wrote:
>>
>> : ...
>> :   Let me rephrase the question: If an access type goes out of scope,
>> : so the things it pointed to become inaccessible, is there any portable
>> : way to prevent an eventual Storage_Error from multiple calls of the
>> : block, without using Unchecked_Deallocation?
>>
>> Yes.  Specify the 'Storage_Size associated with the access-type.
>> The implementation is required to reclaim the storage for the
>> access type when exiting its scope if a 'Storage_Size is specified
>> (see RM95 13.11(18)).
> 
> 
> Yes, indeed! Nice answer, but I was assuming that this obvious approach of
> fixed size allocation was not acceptable, in which case you are definitely
> going to have to use UD I am afraid :-)

Is it common for implementations to allocate the maximum size when the
type is elaborated ?  I had presumed the maximum would just be a limit
beyond which the total of one-at-a-time allocations would not proceed.
In that case I figured from the discussion that setting Storage_Size
to MAX_INT (never intending to get there) would accomplish the deallocation
purpose.

Larry Kilgallen




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-24  0:00 Freeing Pointers to classwide types joecool
                   ` (2 preceding siblings ...)
  1998-09-26  0:00 ` Simon Wright
@ 1998-10-09  0:00 ` Matthew Heaney
  1998-10-09  0:00   ` Niklas Holsti
  3 siblings, 1 reply; 61+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


"joecool" <nobody@nowhere.com> writes:

> I understand (I think) how to dynamically allocate different objects within
> a class and place them in a heterogenous list but I'm not sure if I
> understand how to properly free the memory.
> 
> How do you go about freeing such critters?

I like each specific type in the hierarchy to maintain its own free list
of already-allocated objects.  Provide a class-wide operation that
dynamically dispatches a private Do_Free op.  Something like:

package P is 
   
   type T is abstract null record;

   type T_Access is access all T'Class;
   for T_Access'Storage_Size use 0;
   --
   -- By making this have a storage size of zero, you force 
   -- clients to call a constructor (allocator) for the specific
   -- type.

   procedure Free (O : in out T_Access);
...
private

   procedure Do_Free (O : access T);

end;

package body P is

   procedure Free (O : in out T_Access) is
   begin
      if O /= null then
         Do_Free (O);
         O := null;
      end if;
   end Free;

   procedure Do_Free (O : access T) is
   begin
      null;
   end;

end P;


Now create a derived type:

package P.Q is

   type NT is new T with private;

   function New_NT (...) return T_Access;
...
private

   type NT is ...;

   procedure Do_Free (O : access NT);

end;

package body P.Q is

   Free_List : <list of pointers to NT>;

   function New_NT (...) return T_Access is
   begin
      if Free_List = null then
         allocate new NT object, and return that
      else
         pop item off free list, and return that
      end if;
   end;

   procedure Do_Free (O : access NT) is
   begin
      <put O on the free list>
   end;

end P.Q;


I worked up an example of this kind of thing for the Interpreter
pattern.  Email me if you like a copy of the code/text.

Matt








^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00 ` Tom Moran
  1998-09-25  0:00   ` Bob Fletcher
  1998-09-25  0:00   ` dewarr
@ 1998-10-09  0:00   ` Matthew Heaney
  2 siblings, 0 replies; 61+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


tmoran@bix.com (Tom Moran) writes:

> >freeing the memory once you allocate it
> Look up Unchecked_Deallocation in your Ada text if you are worried
> about manually freeing memory, class-wide or not.

Please don't use Unchecked_Deallocation.  You must take responsibility
for storage management, otherwise you're at the mercy of your compiler
vendor.

(As time goes on, how does repeated use of new/dealloc affect
the heap?  What is the timing behavior?  I worked on a system that made
unbridled use of new/dealloc, and after a while calling allocator new
NEVER RETURNED TO THE CALLER.)

It's very simple to implement your own storage manager.







^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-25  0:00   ` Bob Fletcher
  1998-09-25  0:00     ` dennison
  1998-09-25  0:00     ` Samuel Tardieu
@ 1998-10-09  0:00     ` Matthew Heaney
  1998-10-12  0:00       ` Mats Weber
  2 siblings, 1 reply; 61+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


"Bob Fletcher" <fletcherr@logica.com> writes:

> Tom Moran <tmoran@bix.com> wrote in article
> <360b26a1.41575272@SantaClara01.news.InterNex.Net>...
> > Of course one
> > would also hope
> >   procedure something(....) is
> >       type ptr is access ....
> >       p : ptr: := new ...
> >   ...
> >   end something
> > to free the memory pointed to by 'p' when it leaves procedure
> > something.      
> 
> Really? Isn't the object that is created by the 'new' keyword similar in
> nature to a C++ 'heap' variable, in that although the pointer may go out of
> scope the object will not, and needs to be explicitly destroyed?

No.  When you leave a frame in which an access type is declared, the
storage associated with the access type gets reclaimed automatically.




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-09-26  0:00         ` Tom Moran
  1998-09-27  0:00           ` dewarr
@ 1998-10-09  0:00           ` Matthew Heaney
  1 sibling, 0 replies; 61+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


tmoran@bix.com (Tom Moran) writes:

> > the normal coding would be to do a free operation in the
> >finalization routine
> I'm unable to see a way to code such a finalization routine:
> procedure Finalize(X : in out T) is
> begin
>    -- some code that frees the memory of X if it's on the heap 
>    -- and nulls out the (any) pointer to X
> end Finalize;

No.  You have to take the deallocation up a level, by wrapping the
allocation in a finalizable type.  A while back I posted an example like
this:

procedure Do_Someting (Stack : access Root_Stack'Class) is

   Handle : Iterator_Handle (Stack);

   Iterator : Stack_Iterator renames Get_Iterator (Handle).all;

begin
...

The type looks like

package Stacks is
...
   type Stack_Iterator is 
      abstract tagged limited null record;
   
   <primitive ops for Stack_Iterator>

   type Stack_Iterator_Access is 
      access all Stack_Iterator'Class;

   type Iterator_Handle (Stack : access Root_Stack'Class) is 
      limited private;

   function Get_Iterator 
     (Handle : Iterator_Handle) return Stack_Iterator_Access;

private

   function New_Iterator 
     (Stack : access Stack_Iterator) return Stack_Iterator_Access;

   type Iterator_Handle (...) is 
      new Limited_Controlled with record
         Iter : Stack_Iterator_Access := New_Iterator (Stack);
      end record;

   procedure Finalize (Handle : in out Iterator_Handle);

end;

package body Stacks is 

   procedure Finalize (Handle : in out Iterator_Handle) is
   begin
      <free Handle.Iter>
   end;

end;

                 
Never let a client call allocator new directly.  Let the allocation be
done by a controlled object, so that when the object is finalized, it
automatically reclaims the memory.







^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-02  0:00                                         ` dewarr
@ 1998-10-09  0:00                                           ` Matthew Heaney
  1998-10-09  0:00                                             ` dennison
  0 siblings, 1 reply; 61+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


dewarr@my-dejanews.com writes:

> The answer is no, but so what? This is like asking if there is a way to
> define a function without using the function keyword, or whether there is
> a way to have concurrent execution without using the task keyword.
> Unchecked_Deallocation is for use in such contexts, why on earth worry
> about whether you can do unchecked deallocations without using
> Unchecked_Deallocation?

There are techniques for doing memory reclaimation that don't require
the use of Unchecked_Deallocation.

I think the issue is, Should you use UD without also specifying a
storage pool too?  I would answer, No.  It has been my experience that
using the UD off-the-shelf is a recipe for disaster.




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-09  0:00                                           ` Matthew Heaney
@ 1998-10-09  0:00                                             ` dennison
  1998-10-09  0:00                                               ` Matthew Heaney
  0 siblings, 1 reply; 61+ messages in thread
From: dennison @ 1998-10-09  0:00 UTC (permalink / raw)


In article <m3emsix65f.fsf@mheaney.ni.net>,
  Matthew Heaney <matthew_heaney@acm.org> wrote:

> I think the issue is, Should you use UD without also specifying a
> storage pool too?  I would answer, No.  It has been my experience that
> using the UD off-the-shelf is a recipe for disaster.
>

Pardon my naivete', but how does a storage pool help the situation? Problems I
know of that can happen with manual deallocation are not doing it when you
should (leaks) and doing it too soon (dangling pointers).

I suppose it might help with the leak problem *if* the access type doesn't
happen to be declared at the package level, but that seems to be pretty rare.
What good does it do in the more typical situation?

--
T.E.D.

-----------== Posted via Deja News, The Discussion Network ==----------
http://www.dejanews.com/       Search, Read, Discuss, or Start Your Own    




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-09  0:00                                             ` dennison
@ 1998-10-09  0:00                                               ` Matthew Heaney
  0 siblings, 0 replies; 61+ messages in thread
From: Matthew Heaney @ 1998-10-09  0:00 UTC (permalink / raw)


dennison@telepath.com writes:

> In article <m3emsix65f.fsf@mheaney.ni.net>,
>   Matthew Heaney <matthew_heaney@acm.org> wrote:
> 
> > I think the issue is, Should you use UD without also specifying a
> > storage pool too?  I would answer, No.  It has been my experience that
> > using the UD off-the-shelf is a recipe for disaster.
> >
> 
> Pardon my naivete', but how does a storage pool help the situation?
> Problems I know of that can happen with manual deallocation are not
> doing it when you should (leaks) and doing it too soon (dangling
> pointers).
> 
> I suppose it might help with the leak problem *if* the access type
> doesn't happen to be declared at the package level, but that seems to
> be pretty rare.  What good does it do in the more typical situation?

Sorry - I gave an imcomplete answer.  You also need to create a
controlled abstraction that does the allocation and deallocation.
Typically, the deallocation would be done automatically in the Finalize
operation.

The allocation is either done automatically during initialization, or is
a part of the work done by a constructor of some kind called by the
user.

Type Ada.Strings.Unbounded.Unbounded_String is a good example.  The
allocation is done when you call To_Unbounded_String, and the
deallocation is done when the scope ends in which the object is
declared.

In another post, I gave an example of automatical allocation during
Initialization.  (It was to allocate an active iterator whose type was
limited and unconstrained.)

The storage pool is necessary if you want to precisely control the time
and space behavior of allocation and deallocation.  But of course the
pool is hidden from the client of the (controlled) abstraction - the
access type, the storage pool, the call of new, and the call of
unchecked_deallocation, are all implementation details not available to
the client.






^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-09  0:00 ` Matthew Heaney
@ 1998-10-09  0:00   ` Niklas Holsti
  1998-10-10  0:00     ` Matthew Heaney
  0 siblings, 1 reply; 61+ messages in thread
From: Niklas Holsti @ 1998-10-09  0:00 UTC (permalink / raw)


Matthew Heaney wrote:
  [snip]
> I like each specific type in the hierarchy to maintain its own free list
> of already-allocated objects.  Provide a class-wide operation that
> dynamically dispatches a private Do_Free op.  Something like:
> 
> package P is
> 
>    type T is abstract null record;
                      (* need "tagged" here)
> 
>    type T_Access is access all T'Class;
>    for T_Access'Storage_Size use 0;
>    --
>    -- By making this have a storage size of zero, you force
>    -- clients to call a constructor (allocator) for the specific
>    -- type.

I don't see how the commented statement follows from the LRM text on
the Storage_Size attribute. I'm looking mainly at LRM 3.11(18), which
says that the actual size with be _at least_ the one specified, so
even though you specify zero, the size could be a million units.
In fact, the above code elicits the following message from GNAT:
"Warning: implicit call of Initialize will raise Storage_Error."

Could you explain how your suggestion works?

Niklas Holsti




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-09  0:00   ` Niklas Holsti
@ 1998-10-10  0:00     ` Matthew Heaney
  1998-10-11  0:00       ` Niklas Holsti
  0 siblings, 1 reply; 61+ messages in thread
From: Matthew Heaney @ 1998-10-10  0:00 UTC (permalink / raw)


Niklas Holsti <nholsti@icon.fi> writes:

> Matthew Heaney wrote:
>   [snip]
> > I like each specific type in the hierarchy to maintain its own free list
> > of already-allocated objects.  Provide a class-wide operation that
> > dynamically dispatches a private Do_Free op.  Something like:
> > 
> > package P is
> > 
> >    type T is abstract null record;
>                       (* need "tagged" here)
> > 
> >    type T_Access is access all T'Class;
> >    for T_Access'Storage_Size use 0;
> >    --
> >    -- By making this have a storage size of zero, you force
> >    -- clients to call a constructor (allocator) for the specific
> >    -- type.
> 
> I don't see how the commented statement follows from the LRM text on
> the Storage_Size attribute. I'm looking mainly at LRM 3.11(18), which
> says that the actual size with be _at least_ the one specified, so
> even though you specify zero, the size could be a million units.
> In fact, the above code elicits the following message from GNAT:
> "Warning: implicit call of Initialize will raise Storage_Error."
> 
> Could you explain how your suggestion works?

By specifying that the Storage_Size for an access type is 0, you're
effectively saying that the client isn't allowed to call allocator new.

If you call new for an access type whose storage size is 0, then you'll
get Storage_Error.

What I'm trying to do is remove any doubt that the way for a client to
allocate a new instance of (a descendent of) T is to call a constructor
for the specific type - under no circumstances is a client to call new
directly.





^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-10  0:00     ` Matthew Heaney
@ 1998-10-11  0:00       ` Niklas Holsti
  1998-10-11  0:00         ` Matthew Heaney
  0 siblings, 1 reply; 61+ messages in thread
From: Niklas Holsti @ 1998-10-11  0:00 UTC (permalink / raw)


Matthew Heaney wrote:
> 
> Niklas Holsti <nholsti@icon.fi> writes:
> 
> > Matthew Heaney wrote:
> >   [snip]
> > >
> > >    type T_Access is access all T'Class;
> > >    for T_Access'Storage_Size use 0;
      [snip]
> > In fact, the above code elicits the following message from GNAT:
> > "Warning: implicit call of Initialize will raise Storage_Error."

First, let me correct myself: GNAT actually warns that the implicit
Initialize call will raise Program_Error, not Storage_Error.
Moreover, this occurs with a rather old GNAT version (3.05); the
version in WebAda does not emit this warning, so it was probably a
fault in the old GNAT. Sorry for this confusion.

> If you call new for an access type whose storage size is 0, then you'll
> get Storage_Error.

I don't think the LRM says precisely that. Storage_Error is raised
if there is not enough storage, but defining Storage_Size
as zero does not mean that the available storage is zero, since the
compiler can make the storage pool larger than requested. Of course
this may be an insignificant quibble, if all compilers actually
provide exactly the requested size.

On the other hand, it seems that GNAT (in WebAda) lets one specify
a positive Storage_Size for an access type to a descendant of the
type T, so it would seem possible for clients to use "new" for
descendant types. Doesn't this break your approach?

- Niklas




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-11  0:00       ` Niklas Holsti
@ 1998-10-11  0:00         ` Matthew Heaney
  0 siblings, 0 replies; 61+ messages in thread
From: Matthew Heaney @ 1998-10-11  0:00 UTC (permalink / raw)


Niklas Holsti <nholsti@icon.fi> writes:

> On the other hand, it seems that GNAT (in WebAda) lets one specify
> a positive Storage_Size for an access type to a descendant of the
> type T, so it would seem possible for clients to use "new" for
> descendant types. Doesn't this break your approach?

There's nothing that prevents someone from declaring their own access
type.  

What I was trying to do was say to the user the memory allocation and
deallocation are hidden behind primitive operations provided by the
abstraction.  Somehow you have to tell the client that he isn't supposed
to call new and Unchecked_Deallocation himself.

It has been my experience that compilers obey you when you set the
storage size to 0.  If a client forgets, and he does call allocator new,
then he'll get storage error.  This isn't as nice as detecting the error
at compile time, but it gets the job done.  (Although a good compiler
will tell you at compile-time that the allocation will raise
Storage_Error.)

I follow the philosophy that allocator new (and Unchecked_Deallocation)
are operations used only to _implement_ higher-level operations provided
by an abstraction.

It's not unlike an array or a list.  Those data structures are
primitive, in the sense that they should only be used to implement
higher-level data structures.  A client should never directly use a list
as a data structure.




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-09  0:00     ` Matthew Heaney
@ 1998-10-12  0:00       ` Mats Weber
  1998-10-12  0:00         ` Pat Rogers
  0 siblings, 1 reply; 61+ messages in thread
From: Mats Weber @ 1998-10-12  0:00 UTC (permalink / raw)


Matthew Heaney wrote:

> No.  When you leave a frame in which an access type is declared, the
> storage associated with the access type gets reclaimed automatically.

I am almost sure that this is not required by the standard.




^ permalink raw reply	[flat|nested] 61+ messages in thread

* Re: Freeing Pointers to classwide types
  1998-10-12  0:00       ` Mats Weber
@ 1998-10-12  0:00         ` Pat Rogers
  0 siblings, 0 replies; 61+ messages in thread
From: Pat Rogers @ 1998-10-12  0:00 UTC (permalink / raw)


Mats Weber wrote in message <36222676.182518AA@elca-matrix.ch>...
>Matthew Heaney wrote:
>
>> No.  When you leave a frame in which an access type is declared,
the
>> storage associated with the access type gets reclaimed
automatically.
>
>I am almost sure that this is not required by the standard.

It is guaranteed *if one specifies a storage size*, by RM 13.11(18):

18   If Storage_Size is specified for an access type, then the
Storage_Size of this pool is at least that requested, and the
storage for the pool is reclaimed when the master containing the
declaration of the access type is left. ...


-- pat

Patrick Rogers
http://www.classwide.com
progers@acm.org






^ permalink raw reply	[flat|nested] 61+ messages in thread

end of thread, other threads:[~1998-10-12  0:00 UTC | newest]

Thread overview: 61+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1998-09-24  0:00 Freeing Pointers to classwide types joecool
1998-09-25  0:00 ` alan walkington
1998-09-25  0:00 ` Tom Moran
1998-09-25  0:00   ` Bob Fletcher
1998-09-25  0:00     ` dennison
1998-09-25  0:00     ` Samuel Tardieu
1998-10-09  0:00     ` Matthew Heaney
1998-10-12  0:00       ` Mats Weber
1998-10-12  0:00         ` Pat Rogers
1998-09-25  0:00   ` dewarr
1998-09-25  0:00     ` Tom Moran
1998-09-25  0:00       ` dewarr
1998-09-26  0:00     ` Tom Moran
1998-09-26  0:00       ` dewarr
1998-09-26  0:00         ` Tom Moran
1998-09-27  0:00           ` dewarr
1998-09-27  0:00             ` Tom Moran
1998-09-28  0:00               ` dewarr
1998-09-28  0:00                 ` Tom Moran
1998-09-28  0:00                   ` dewarr
1998-09-28  0:00                     ` Tom Moran
1998-09-28  0:00                       ` Pat Rogers
1998-09-28  0:00                         ` Tom Moran
1998-09-28  0:00                           ` Pat Rogers
1998-09-29  0:00                           ` dewarr
1998-09-29  0:00                             ` Tom Moran
1998-09-30  0:00                               ` Tom Moran
1998-10-01  0:00                                 ` dewar
1998-10-01  0:00                                   ` Tom Moran
1998-10-01  0:00                                     ` dewarr
1998-10-01  0:00                                     ` dewarr
1998-10-01  0:00                                       ` Tom Moran
1998-10-01  0:00                                     ` Samuel Tardieu
1998-10-01  0:00                                       ` Tom Moran
1998-10-01  0:00                                         ` dennison
1998-10-01  0:00                                         ` Tucker Taft
1998-10-01  0:00                                           ` Tom Moran
1998-10-02  0:00                                           ` dewarr
1998-10-02  0:00                                             ` Larry Kilgallen
1998-10-02  0:00                                               ` dewarr
1998-10-02  0:00                                           ` dennison
1998-10-02  0:00                                             ` dewarr
1998-10-02  0:00                                         ` dewarr
1998-10-09  0:00                                           ` Matthew Heaney
1998-10-09  0:00                                             ` dennison
1998-10-09  0:00                                               ` Matthew Heaney
1998-09-28  0:00                       ` Tom Moran
1998-09-28  0:00                         ` Brian Rogoff
1998-09-28  0:00                   ` dewarr
1998-09-28  0:00                     ` Richard D Riehle
1998-09-28  0:00                       ` Pat Rogers
1998-09-29  0:00                       ` dewarr
1998-10-09  0:00           ` Matthew Heaney
1998-10-09  0:00   ` Matthew Heaney
1998-09-26  0:00 ` Simon Wright
1998-10-09  0:00 ` Matthew Heaney
1998-10-09  0:00   ` Niklas Holsti
1998-10-10  0:00     ` Matthew Heaney
1998-10-11  0:00       ` Niklas Holsti
1998-10-11  0:00         ` Matthew Heaney
  -- strict thread matches above, loose matches on Subject: below --
1998-09-25  0:00 bpr5549

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox