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.9 required=5.0 tests=BAYES_00 autolearn=ham autolearn_force=no version=3.4.4 X-Google-Thread: 103376,8f7d6c5172a1d41b X-Google-Attributes: gid103376,public X-Google-Language: ENGLISH,ASCII-7-bit Path: g2news2.google.com!news3.google.com!border1.nntp.dca.giganews.com!nntp.giganews.com!local01.nntp.dca.giganews.com!nntp.megapath.net!news.megapath.net.POSTED!not-for-mail NNTP-Posting-Date: Tue, 23 Jan 2007 18:56:09 -0600 From: "Randy Brukardt" Newsgroups: comp.lang.ada References: <3vwf1b4b2ntl$.l9n17zmh9v8a$.dlg@40tude.net> 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 X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 6.00.2800.1807 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2800.1807 Message-ID: NNTP-Posting-Host: 64.32.209.38 X-Trace: sv3-DcJJRrNG+Lr3zqsA1XL3ZRE9A3i0Bo6s7Pe/7aPfRQHupl0l8+lBF9CjqIkQwY+WeZIFPzyoqshGKC8!CVo+47A5iLPhrdGQmjRBafiAN5Nvi2tl5hajoeXLN/dNOAQ1PEKytSjv33JTYN3h2UkApkcGqLht!VmSArysW2COVEw== X-Complaints-To: abuse@megapath.net X-DMCA-Complaints-To: abuse@megapath.net X-Abuse-and-DMCA-Info: Please be sure to forward a copy of ALL headers X-Abuse-and-DMCA-Info: Otherwise we will be unable to process your complaint properly X-Postfilter: 1.3.32 Xref: g2news2.google.com comp.lang.ada:8456 Date: 2007-01-23T18:57:33-06:00 List-Id: "Dmitry A. Kazakov" 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.