comp.lang.ada
 help / color / mirror / Atom feed
From: bobduff@world.std.com (Robert A Duff)
Subject: Re: Free'ing extended types
Date: 1996/04/29
Date: 1996-04-29T00:00:00+00:00	[thread overview]
Message-ID: <DqMH63.Jvw@world.std.com> (raw)
In-Reply-To: 3184803D.1208@ehs.ericsson.se


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




  reply	other threads:[~1996-04-29  0:00 UTC|newest]

Thread overview: 26+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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         ` 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-05-21  0:00         ` Dale Stanbrough
1996-05-21  0:00           ` Robert A Duff
1996-04-29  0:00   ` Free'ing extended types Laurent Guerby
1996-04-29  0:00     ` Robert A Duff
  -- strict thread matches above, loose matches on Subject: below --
1996-04-26  0:00 Jonas Nygren
1996-04-26  0:00 ` Laurent Guerby
1996-04-27  0:00   ` Jerry van Dijk
1996-04-28  0:00     ` Robert Dewar
1996-04-28  0:00   ` Jonas Nygren
replies disabled

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