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=-0.3 required=5.0 tests=BAYES_00, REPLYTO_WITHOUT_TO_CC autolearn=no 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!news.glorb.com!newsgate.cistron.nl!xs4all!feeder.news-service.com!feeder.news-service.com!feeder1.cambrium.nl!feed.tweaknews.nl!193.141.41.141.MISMATCH!npeer1.de.kpn-eurorings.net!npeer-devel!newsfeed.arcor.de!newsspool2.arcor-online.net!news.arcor.de.POSTED!not-for-mail From: "Dmitry A. Kazakov" Subject: Re: [Revisited] How to get around "access type must not be outside generic unit" Newsgroups: comp.lang.ada User-Agent: 40tude_Dialog/2.0.15.1 MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Reply-To: mailbox@dmitry-kazakov.de Organization: cbb software GmbH References: <3vwf1b4b2ntl$.l9n17zmh9v8a$.dlg@40tude.net> Date: Wed, 24 Jan 2007 12:42:21 +0100 Message-ID: <1u2mhr9ypij4u.bn3yayn7o9l3$.dlg@40tude.net> NNTP-Posting-Date: 24 Jan 2007 12:42:21 CET NNTP-Posting-Host: a8f73da5.newsspool2.arcor-online.net X-Trace: DXC=>c?\?n<^6IH2jYf>V4L0gLA9EHlD;3YcB4Fo<]lROoRAFl8W>\BH3YBRjYUQ23?7:ODNcfSJ;bb[EFCTGGVUmh?DLK[5LiR>kgBOKRCW>@5XmI X-Complaints-To: usenet-abuse@arcor.de Xref: g2news2.google.com comp.lang.ada:8475 Date: 2007-01-24T12:42:21+01:00 List-Id: On Tue, 23 Jan 2007 18:57:33 -0600, Randy Brukardt wrote: > "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. ;-) Let's take GtkAda as an example. The facts are: 1. It interfaces GTK+ (C++) 2. It is full of this package Glib is ... type Boxed_Copy is access function (Boxed : System.Address) return System.Address; pragma Convention (C, Boxed_Copy); type Boxed_Free is access procedure (Boxed : System.Address); pragma Convention (C, Boxed_Free); function Boxed_Type_Register_Static (Name : String; Copy : Boxed_Copy; Free : Boxed_Free) return GType; How can I (well, ACT (:-)) apply Convention (C,...) on an anonymous access type?! > 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. And what Janus/Ada would do if it meets pragma Convention (C, Foo); ? >> 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. I meant (1 and 2 and 3), not (1 or 2 or 3)! (:-)) > 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. OK, that's definitely better than Unchecked_Conversion. In Ada 95 it was enough to add a declaration of the subprogram to the specification, now we also need an access object. This is strange, at least not obvious. Why should it change anything? I mean, if it is semantically correct, then why the compiler cannot deduce it? Is it semantically correct? In the case with Glib above, would it be possible to instantiate a generic package in a local scope; call to Boxed_Type_Register_Static passing a constant as you described; and then leave the scope? generic package Foo is ... private function Copy (Boxed : System.Address) return System.Address; pragma Convention (C, Copy); procedure Free (Boxed : System.Address); pragma Convention (C, Free); Copy_Ptr : constant Boxed_Copy := Copy'Access; Free_Ptr : constant Boxed_Free := Free'Access; end Foo; package body Foo is function Copy (Boxed : System.Address) return System.Address is ... procedure Free (Boxed : System.Address) is ... ... begin ... := Boxed_Type_Register_Static ("Foo", Copy_Ptr, Free_Ptr); end Foo; ... declare My_Foo is new Foo; -- Is it legal in Ada 2005? begin ... end; -- Boom! -- Regards, Dmitry A. Kazakov http://www.dmitry-kazakov.de