comp.lang.ada
 help / color / mirror / Atom feed
* Subprogram access types and generic packages
@ 1997-03-18  0:00 Greg Bond
  1997-03-19  0:00 ` Robert A Duff
  1997-03-20  0:00 ` Tucker Taft
  0 siblings, 2 replies; 3+ messages in thread
From: Greg Bond @ 1997-03-18  0:00 UTC (permalink / raw)



I'm trying to write a generic package that will register an access type
of one of its internal subprograms with an external subprogram when
instantiated. I get the error message:

pkg.adb:12:14: access type must not be outside generic body

Why not? 

Here's a simple bit of code that generates this error: (gnatmake
access_test)

--------------------------------------------------
access_test.adb
--------------------------------------------------

with Pkg;

procedure Access_Test is

   Val: constant Integer := 10;

   package Test is new Pkg (Val);
   use Test;

begin
   null;
end Access_Test;


--------------------------------------------------
pkg.ads
--------------------------------------------------

generic
   Const: Integer;

package Pkg is

   pragma Elaborate_Body (Pkg);

end Pkg;

--------------------------------------------------
pkg.adb
--------------------------------------------------

with Reg; use Reg;

package body Pkg is

   procedure Proc is
   begin
      null;
   end Proc;

begin

   Register (Proc'Access);

end Pkg;

--------------------------------------------------
reg.ads
--------------------------------------------------

package Reg is

   type Proc_Alias is access procedure;

   procedure Register (Proc: Proc_Alias);

end Reg;

--------------------------------------------------
reg.adb
--------------------------------------------------

package body Reg is

   procedure Register (Proc: in Proc_Alias) is
   begin

    null;

   end Register;

end Reg;

--
* Greg Bond                       * Dept. of Electrical and Computer Eng.  
* email: bond@ee.ubc.ca           * Univ. of British Columbia      
* voice: (604) 822 0899           * 2356 Main Mall                 
* fax:   (604) 822 5949           * Vancouver, BC              
* web: http://www.ee.ubc.ca/~bond * Canada, V6T 1Z4                                       





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

* Re: Subprogram access types and generic packages
  1997-03-18  0:00 Subprogram access types and generic packages Greg Bond
@ 1997-03-19  0:00 ` Robert A Duff
  1997-03-20  0:00 ` Tucker Taft
  1 sibling, 0 replies; 3+ messages in thread
From: Robert A Duff @ 1997-03-19  0:00 UTC (permalink / raw)



In article <bond-ya023680001803971613240001@nntp.ucs.ubc.ca>,
Greg Bond <bond@ee.ubc.ca> wrote:
>I'm trying to write a generic package that will register an access type
>of one of its internal subprograms with an external subprogram when
>instantiated. I get the error message:
>
>pkg.adb:12:14: access type must not be outside generic body
>
>Why not? 

The rule is the last sentence of 3.10.2(32).  The reasons for the rule
are explained in AARM-3.10.2(32.a).

Workaround: Declare the procedure in the private part of the generic
package.  Move the instantiation to library level (i.e. as a library
unit, or in a library package).

>Here's a simple bit of code that generates this error: (gnatmake
>access_test)
>
>--------------------------------------------------
>access_test.adb
>--------------------------------------------------
>
>with Pkg;
>
>procedure Access_Test is
>
>   Val: constant Integer := 10;
>
>   package Test is new Pkg (Val);

Note that this instantiation could cause a dangling pointer -- Test.Proc
is nested within Access_Test, but a pointer to Test.Proc could survive
after Access_Test returns.  (E.g. suppose "Register" saved its parameter
into a global variable.)  You must do the instantiation at library level
so this can't happen.  And you must declare Proc in the spec of the
generic so that the compiler can check for the error at instantiation
time.

>   use Test;
>
>begin
>   null;
>end Access_Test;
>
>
>--------------------------------------------------
>pkg.ads
>--------------------------------------------------
>
>generic
>   Const: Integer;
>
>package Pkg is
>
>   pragma Elaborate_Body (Pkg);
>
>end Pkg;
>
>--------------------------------------------------
>pkg.adb
>--------------------------------------------------
>
>with Reg; use Reg;
>
>package body Pkg is
>
>   procedure Proc is
>   begin
>      null;
>   end Proc;
>
>begin
>
>   Register (Proc'Access);
>
>end Pkg;
>
>--------------------------------------------------
>reg.ads
>--------------------------------------------------
>
>package Reg is
>
>   type Proc_Alias is access procedure;
>
>   procedure Register (Proc: Proc_Alias);
>
>end Reg;
>
>--------------------------------------------------
>reg.adb
>--------------------------------------------------
>
>package body Reg is
>
>   procedure Register (Proc: in Proc_Alias) is
>   begin
>
>    null;
>
>   end Register;
>
>end Reg;

- Bob




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

* Re: Subprogram access types and generic packages
  1997-03-18  0:00 Subprogram access types and generic packages Greg Bond
  1997-03-19  0:00 ` Robert A Duff
@ 1997-03-20  0:00 ` Tucker Taft
  1 sibling, 0 replies; 3+ messages in thread
From: Tucker Taft @ 1997-03-20  0:00 UTC (permalink / raw)



Greg Bond (bond@ee.ubc.ca) wrote:

: I'm trying to write a generic package that will register an access type
: of one of its internal subprograms with an external subprogram when
: instantiated. I get the error message:

: pkg.adb:12:14: access type must not be outside generic body

: Why not? 

Because the RM says so ;-).  RM95 3.10.2(32) says:

 P'Access
   ... If the subprogram denoted by P is declared within a generic body,
   S [the access-to-subp type] shall be declared within the generic body.

The annotated RM goes on to say:
    ... This rule is partly to prevent contract model problems with respect
    to accessibility rules, and partly to ease shared-generic-body 
    implementations, in which a subprogram declared in an instance needs
    to have a different calling convention from other subprograms with
    the same profile.

The way to avoid the problem is to move the declaration of the subprogram
up into the private part of the generic spec.  This gives the shared-generic
implementation the chance to create a unique wrapper at each instantiation,
so a simple address (rather than an address + a pointer to an "instance
descriptor) is sufficient to call the subprogram.

If none of the above makes sense, then revert to my first explanation
(the RM says so) or talk to Randy Brukardt or other compiler implementor
whose compiler uses "universal" generic sharing.

: * Greg Bond                       * Dept. of Electrical and Computer Eng.  
: * email: bond@ee.ubc.ca           * Univ. of British Columbia      
: * voice: (604) 822 0899           * 2356 Main Mall                 
: * fax:   (604) 822 5949           * Vancouver, BC              
: * web: http://www.ee.ubc.ca/~bond * Canada, V6T 1Z4                                       
-Tucker Taft   stt@inmet.com   http://www.inmet.com/~stt/
Intermetrics, Inc.  Burlington, MA  USA




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

end of thread, other threads:[~1997-03-20  0:00 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1997-03-18  0:00 Subprogram access types and generic packages Greg Bond
1997-03-19  0:00 ` Robert A Duff
1997-03-20  0:00 ` Tucker Taft

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