comp.lang.ada
 help / color / mirror / Atom feed
From: "Randy Brukardt" <randy@rrsoftware.com>
Subject: Re: [Revisited] How to get around "access type must not be outside generic unit" (was: How to get around "access type must not be outside generic unit")
Date: Tue, 23 Jan 2007 18:57:33 -0600
Date: 2007-01-23T18:57:33-06:00	[thread overview]
Message-ID: <WcKdnWhWUJc0MyvYnZ2dnUVZ_rKvnZ2d@megapath.net> (raw)
In-Reply-To: 3vwf1b4b2ntl$.l9n17zmh9v8a$.dlg@40tude.net

"Dmitry A. Kazakov" <mailbox@dmitry-kazakov.de> wrote in message
news:3vwf1b4b2ntl$.l9n17zmh9v8a$.dlg@40tude.net...
...
> This is a quite frequent pattern which now is broken, for a good reason
> BTW, because it was unsafe. Obviously Register cannot be touched.

Well, the best solution is to touch Register, and give it an anonymous
access type parameter (which doesn't do accessibility checks). Even better
is to avoid C interfacing. ;-)

> So the
> only solution is declaration of a local access type with a consequent
> Unchecked_Conversion on it:

That won't work in a compiler that does generic code sharing (like
Janus/Ada). Subprograms in a generic have an extra hidden parameter to carry
the instance descriptor, and thus the profile doesn't match that of a
routine outside of a generic. There is absoletely no way to change this
inside of the generic body short of completely abandoning the code sharing
model.

....
> Potential solution:
> ------------------------
> 1. Drop all accessibility checks for access to subprogram with
>
>    pragma Convention (C, ...).
>
>    Rationale: C subprograms are global

Won't work in a generic code shared body. Also, it would cause problems if
your C routine written in Ada did up-level accesses - you'd have all of the
dangling pointer issues and no checks to prevent them. C routines absolutely
have to be written at the library level.

> 2. Prohibit pragma Convention (C, ...) in generic bodies for any
subprogram
> types not mentioned in the specification AND in all local scopes.

That's already effectively true, since you can't do anything useful with it.
But I don't know how this helps solve your problem.

> 3. Prohibit instantiation of generic units with pragma Convention (C, ...)
> used in specifications otherwise as at the library level.
>
> The result should be the package Usage required to be instantiated on
> library level, with Install exposed in the specification of. Explicit
> pragma Convention (C, ...) in the specification would reject
instantiations
> without looking into bodies.

There isn't any reason to do this. It is trivial to write the specification
of a generic so that it can only be instantiated at the library level.

But in any case, the solution to your problem (as always) is to put the
'Access into the private part of the specification. Do that with an
appropriate constant declaration. (If the parameter type of Register was
anonymous, there is no problem, so there must be a named type that can be
used.) Doing so will force the generic to be instantiated at the library
level. So I don't see any problem with this example, and no
Unchecked_Conversion.

That is:

> ---- usage.ads
> generic
>    type Data_Type is private;
> package Usage is
>
>    function Install return Boolean ;
>    procedure Doit( X : in out Data_Type );
> private --- NEW
      Install_Access : constant Register_Sub_Type := Install'Access; -- New
> end Usage;
>
> ---- usage.adb
> with Base;   use Base;
>
> package body Usage is
>
>    function Install return Boolean is
>    begin
>       return True;
>    end Install;
>
>    procedure Doit( X : in out Data_Type ) is
>    begin
>       null;
>    end Doit;
>
> begin
>    Register("Doit", Install_Access);    -- Fine.
> end Usage;

And if the routine isn't declared in the spec, add it also to the private
part.

                              Randy.





  reply	other threads:[~2007-01-24  0:57 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-12-17 10:07 How to get around "access type must not be outside generic unit" Michael Erdmann
2006-12-17 12:45 ` Pascal Obry
2006-12-17 14:28   ` Michael Erdmann
2006-12-17 15:53     ` Pascal Obry
2006-12-17 20:49     ` Robert A Duff
2006-12-18  3:35   ` Brian May
2006-12-18  7:49     ` Jean-Pierre Rosen
2006-12-18 23:15       ` Brian May
2006-12-19  1:48         ` Randy Brukardt
2006-12-19  7:41         ` Jean-Pierre Rosen
2006-12-18 20:32     ` Michael Erdmann
2006-12-18 20:57       ` Randy Brukardt
2007-01-23 18:18 ` [Revisited] How to get around "access type must not be outside generic unit" (was: How to get around "access type must not be outside generic unit") Dmitry A. Kazakov
2007-01-24  0:57   ` Randy Brukardt [this message]
2007-01-24 11:42     ` [Revisited] How to get around "access type must not be outside generic unit" Dmitry A. Kazakov
2007-01-24 11:58       ` Ludovic Brenta
2007-01-24 13:46         ` Dmitry A. Kazakov
2007-01-24 20:50       ` Randy Brukardt
2007-01-25 11:07         ` Dmitry A. Kazakov
replies disabled

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