comp.lang.ada
 help / color / mirror / Atom feed
From: Robert A Duff <bobduff@shell01.TheWorld.com>
Subject: Re: Run-Time Type Assignment
Date: Fri, 30 Aug 2002 22:54:08 GMT
Date: 2002-08-30T22:54:08+00:00	[thread overview]
Message-ID: <wccsn0wc60f.fsf@shell01.TheWorld.com> (raw)
In-Reply-To: H1MzHv.F2y@world.std.com

"Ben Brosgol" <brosgol@world.std.com> writes:

> Hmm, I try not to say too many silly things (unless I flag them with
> smileys) so I guess I need to give some additional explanation for my
> comment.

OK, Ben, I apologize for the "silly" accusation.  I shouldn't use such
inflamatory rhetoric.

But I stand by my claims: 'Unrestricted_Access is not safe, and not portable.

> First, I was not claiming that 'Unrestricted_Access is a completely safe
> construct.  Obviously you can create dangling references.

Which is why I said 'Unrestricted_Access is "unsafe".

> But lots of programs have no need for the generality of stuffing a (pointer
> to a) subprogram in a data structure, or assigning it to a variable; they
> only need to pass subprograms as run-time parameters.  For such programs it
> will be perfectly safe to use 'Unrestricted_Access to pass a nested
> subprogram as a parameter; there is no danger of dangling references, and
> you still get the other checks that 'Access entails.  (Phrased differently:
> the context of the original discussion was whether anything that could be
> done in Pascal could be done in Ada.  So if you have a Pascal program that
> passes a procedure or function as a parameter, and then convert the program
> to Ada, there is no lack of safety in using Unrestricted_Access.)

Well, that's not Ada, that's GNAT Ada, but still...

>...  I see
> this as different from the array indexing case.  It is hard, if all you want
> to do is pass a subprogram as a parameter, to accidentally store it into a
> data structure.

True.  However, it is perfectly reasonable to save procedure pointers
into globals -- that's what the Ada 95 features of access-to-procedure
and P'Access are for.  So suppose we have a procedure:

    type Proc is access procedure;
    procedure Mumble(X: Proc);

I'm not going to show you the body of Mumble, because that would be
cheating.  Now is it OK to pass Nested_Proc'Unrestricted_Access
to Mumble?  There's no way to tell.  (Well, you can look at the
comments, but you can't claim that as language support.)

>...  It is easy to make a programming error and accidentally
> have an array index out of bounds.
> 
> > >...(I.e.,
> > > Unrestricted_Access still entails the other checks required by the
> language;
> > > e.g. static subtype conformance for corresponding formals, matching
> > > conventions.)  For example:
> 
> > Well, it's nice that it detects *some* errors (it detects misspellings
> > like 'Unrestricted_Acess, too!), but it doesn't detect dangling
> > pointers.
> 
> It's not clear when to do the detection (see below).

It's quite clear to me.  We need a new kind of access-to-procedure type,
a "limited" one that doesn't allow assignment.  Then passing nested
procedures to the limited type is OK, and assignment is illegal (that
is, the detection happens when you try to assign (or return, etc)).
At least, that's *one* safe design.  There are others.

> > >   declare
> > >     procedure Q is begin null; end Q;
> > >   begin
> > >     Ref := Q'Unrestricted_Access; -- OK
> >
> > That's the problem (the above "OK").  If you call Ref.all later, you're
> > in trouble.  GNAT thinks it's OK, but it is *not* OK.
> 
> Might or might not be OK; depends on your definition of "later".  You're OK
> if the call is only from the block that declares Q.  (And you're probably
> still OK even if the call is from an outer scope, if (as is the case here) Q
> does not make any up-level references to stack variables.)

By "later", I meant, "after that block is left".

In most real examples, Q *does* make up-level refs -- that's why it is
nested.  Anyway, whether or not Q refers to globals, calling Q when it
no longer exists should be considered an error -- and GNAT does not
detect this error.

> But the point is not that Unrestricted_Access can lead to dangling
> references.

I disagree -- the point (I was trying to make) is exactly that
'Unrestricted_Access is unsafe in that it can cause dangling pointers,
which is not possible for the corresponding feature in Pascal.

The key point to understanding this issue is to see that the Pascal
feature is a different feature from Ada 95's access-to-procedure.
'Unrestricted_Access tries to combine them into one -- there lies the
trouble.

The Pascal feature is to allow procedures to be passed inward,
but not assigned or returned.  That's what I call "downward closures".

The Ada 95 feature is to allow top level procedures to be passed around
and returned and assigned into global variables -- and then called much
later.  That's what I call "callbacks".

Both features are useful; they're not the same feature.
Both can be supported safely.
It's unfortunate, IMHO, that Ada 95 supports only one of them,
and that GNAT supports the other unsafely.

>...It's that you still get the checks as for 'Access except for
> scope accessibility, and that you don't need that check if you are only
> passing a subprogram as a parameter and not assigning it to a variable.

If you pass it as a parameter, it could be assigned to a global
variable.  That's the problem.

> -Ben

- Bob



  reply	other threads:[~2002-08-30 22:54 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-08-28  6:53 Run-Time Type Assignment Robert C. Leif
2002-08-28 11:04 ` Robert Dewar
2002-08-28 13:35   ` Robert A Duff
2002-08-28 14:56     ` Larry Kilgallen
2002-08-28 14:31       ` Robert A Duff
2002-08-28 14:59         ` Lutz Donnerhacke
2002-08-28 22:32           ` Robert A Duff
2002-08-29 22:55           ` Dmitry A.Kazakov
2002-08-28 18:03         ` Frank J. Lhota
2002-08-28 18:37           ` Pat Rogers
2002-08-28 22:47           ` Robert A Duff
2002-08-29 13:32             ` Ben Brosgol
2002-08-29 13:52               ` SIMON Claude
2002-08-29 14:30                 ` Robert A Duff
2002-08-29 18:27                   ` Randy Brukardt
2002-08-29 14:56               ` Robert A Duff
2002-08-30  3:04                 ` Ben Brosgol
2002-08-30 22:54                   ` Robert A Duff [this message]
2002-08-29 15:09               ` Larry Kilgallen
2002-08-29 14:29                 ` Marin D. Condic
2002-08-28 13:41 ` Robert A Duff
2002-08-28 17:15 ` Hyman Rosen
2002-08-28 20:27 ` Björn Lundin
     [not found] <002a01c24e5f$9ee347b0$789a0844@robertqgx6k4x9>
2002-08-28 11:33 ` sk
     [not found] ` <3D6CB4F5.F4E05D76@myob.com>
2002-08-28 11:37   ` sk
2002-08-28 15:39   ` Robert C. Leif
2002-08-28 18:53     ` Jeffrey Carter
2002-08-28 20:54   ` Robert C. Leif
2002-08-28 22:55     ` Robert A Duff
2002-08-29  3:18       ` Robert C. Leif
     [not found] <005101c24ea9$0de9c960$789a0844@robertqgx6k4x9>
2002-08-28 16:06 ` sk
2002-08-28 22:44   ` tmoran
2002-08-29  0:37   ` tmoran
replies disabled

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