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,6e696296ba7c3482 X-Google-Attributes: gid103376,public From: adam@irvine.com (Adam Beneschan) Subject: Re: parameters in bindings Date: 1996/03/23 Message-ID: <4ivpfk$sjq@krusty.irvine.com>#1/1 X-Deja-AN: 143811390 references: organization: /z/news/newsctl/organization newsgroups: comp.lang.ada Date: 1996-03-23T00:00:00+00:00 List-Id: mg@harp.camb.inmet.com (Mitch Gart) writes: >Suppose we have a C function > > int f (int * param1, int ** param2); > >(For the non-C crowd this is a function named f which takes 2 >parameters and returns an integer. The first parameter is a >pointer to an integer and the second is a pointer to a pointer >to an integer.) > >How do we best interface to this in Ada 95? > >Method 1 uses "in out" parameters and would be the best Ada >interface (ignoring the question about "in out" versus "out"): > > type int_access is access all int; -- int defined somewhere > > function f (param1: in out int; > param2: in out int_access) return int; "in out" wouldn't necessarily do what you want anyway. If this weren't an interfaced routine, "in out" scalar parameters should be implemented as copy-in/copy-back instead of by reference (RM95 6.2(3)), which means that the code wouldn't be passing the addresses of the integer or the pointer. I'm sure that the compiler could break this rule in the case of interfaced procedures, and pass them as addresses anyway; you'd have to figure out whether your compiler does that. Some compilers have pragmas that let you specify the passing mechanism for each parameter of an interfaced routine. >This is unfortunately illegal, out parameters are not allowed for >functions. There have been long threads discussing this restriction >and it sounds like it will not be changed. Some compilers, by the way, have a pragma that can be applied to interfaced *procedures* that says "This procedure really acts like a function; please take the return value of the function and stick it in one of my OUT parameters." VAX Ada does this, in particular. >Method 2 uses anonymous access types. I have used this method all >over the place in a number of bindings such as X11Ada and Win32Ada. > > type int_access is access all int; -- int defined somewhere > > function f (param1: access int; > param2: access int_access) return int; > >I have recently learned this is a fundamental error because an Ada 95 >rule makes passing null for param1 or param2 illegal (see LRM 4.2(7) >and 4.6(49)). Many of the C functions in the bindings allow null >to be passed, with a meaning like "if the parameter is non-null assign >a result to the place where it points". > >Method 3 uses all named access types: > > type int_access is access all int; -- int defined somewhere > type int_access_access is access all int_access; > > function f (param1: int_access; > param2: int_access_access) return int; > >This works but to me it seems ugly because extra access types are >introduced which are otherwise unnecessary. > >Because of the illegal-null problem in method 2 I guess I'm going to >make a wholesale change to the bindings and use method 3. Before I >make that change does anybody have any better ideas? When I interface to C or VMS services or whatever, I usually just use SYSTEM.ADDRESS parameters and pass the 'address of everything. Not pretty, but it gets the job done. Also, my impression is that you can count on what will happen when you pass a SYSTEM.ADDRESS parameter more than you can count on an Ada access type looking exactly the same as a C pointer. If your compiler uses something for SYSTEM.ADDRESS that doesn't look like a C pointer, hopefully it provides some other pragma or attribute that will let you pass the right value. -- Adam