Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Subprogram access types and generic packages

4 views
Skip to first unread message

Greg Bond

unread,
Mar 18, 1997, 3:00:00 AM3/18/97
to

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: bo...@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


Robert A Duff

unread,
Mar 19, 1997, 3:00:00 AM3/19/97
to

In article <bond-ya02368000...@nntp.ucs.ubc.ca>,

Greg Bond <bo...@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.

- Bob

Tucker Taft

unread,
Mar 20, 1997, 3:00:00 AM3/20/97
to

Greg Bond (bo...@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: bo...@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 s...@inmet.com http://www.inmet.com/~stt/
Intermetrics, Inc. Burlington, MA USA

0 new messages