From mboxrd@z Thu Jan 1 00:00:00 1970 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on polar.synack.me X-Spam-Level: X-Spam-Status: No, score=-1.3 required=5.0 tests=BAYES_00,INVALID_MSGID autolearn=no autolearn_force=no version=3.4.4 X-Google-Language: ENGLISH,ASCII-7-bit X-Google-Thread: 103376,b7ecd0508d245308 X-Google-Attributes: gid103376,public From: bobduff@world.std.com (Robert A Duff) Subject: Re: Subprogram access types and generic packages Date: 1997/03/19 Message-ID: #1/1 X-Deja-AN: 226807020 References: Organization: The World Public Access UNIX, Brookline, MA Newsgroups: comp.lang.ada Date: 1997-03-19T00:00:00+00:00 List-Id: In article , Greg Bond 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