comp.lang.ada
 help / color / mirror / Atom feed
* parameters in bindings
@ 1996-03-22  0:00 Mitch Gart
  1996-03-22  0:00 ` Robert Dewar
  1996-03-23  0:00 ` Adam Beneschan
  0 siblings, 2 replies; 5+ messages in thread
From: Mitch Gart @ 1996-03-22  0:00 UTC (permalink / raw)


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;

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.

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?

- Mitch Gart
- mg@inmet.com




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: parameters in bindings
  1996-03-22  0:00 parameters in bindings Mitch Gart
@ 1996-03-22  0:00 ` Robert Dewar
  1996-03-26  0:00   ` Mitch Gart
  1996-03-23  0:00 ` Adam Beneschan
  1 sibling, 1 reply; 5+ messages in thread
From: Robert Dewar @ 1996-03-22  0:00 UTC (permalink / raw)


"This works but to me it seems ugly because extra access types are
introduced which are otherwise unnecessary."

That's odd, it's a bit like saying, I need some arrays, but I seem to have
to introduce some array types which are otherwise unnecessary.

Your argument is accurate, these extra access types are necessary. I
suggest introducing them in a child of Interfaces.C so that a standard
set is used.





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: parameters in bindings
  1996-03-22  0:00 parameters in bindings Mitch Gart
  1996-03-22  0:00 ` Robert Dewar
@ 1996-03-23  0:00 ` Adam Beneschan
  1 sibling, 0 replies; 5+ messages in thread
From: Adam Beneschan @ 1996-03-23  0:00 UTC (permalink / raw)


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




^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: parameters in bindings
  1996-03-26  0:00   ` Mitch Gart
@ 1996-03-26  0:00     ` Robert Dewar
  0 siblings, 0 replies; 5+ messages in thread
From: Robert Dewar @ 1996-03-26  0:00 UTC (permalink / raw)


Mitch says

"    type thing is record ... end record;
    type thing_access is access all thing;
    procedure P (param: thing_access);
    x: aliased thing;
  begin
    p(x'access);

The type thing_access is an extra junk type that has no other use
in the program.  No actual objects of type thing_access are ever
declared or used.  It is just there to allow the parameter to be
declared.  This extra type is not needed with method 1 of declaring P.

To me the declaration of thing_access is extra useless baggage."

And no doubt a C programmer would find many type declarations in an
Ada program "useless baggage", but the response would be the same,
types are important. thing_access is not an extra junk type that
is not used, it is the type of values passed to procedure P.

I still don't like the general use of anonymous access types for this,
they just don't seem right, since an access to an object should be
exactly that, an access to an object, so it makes no conceptual sense
for an access parameter to be null. A VALUE of an access type can on
the other hand perfectly well be null.
\x1adp
\x1ap





^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: parameters in bindings
  1996-03-22  0:00 ` Robert Dewar
@ 1996-03-26  0:00   ` Mitch Gart
  1996-03-26  0:00     ` Robert Dewar
  0 siblings, 1 reply; 5+ messages in thread
From: Mitch Gart @ 1996-03-26  0:00 UTC (permalink / raw)


Robert Dewar (dewar@cs.nyu.edu) wrote:
: "This works but to me it seems ugly because extra access types are
: introduced which are otherwise unnecessary."

: That's odd, it's a bit like saying, I need some arrays, but I seem to have
: to introduce some array types which are otherwise unnecessary.

Here's a slightly different example.  Method 1 of declaring P:

    type thing is record ... end record;
    procedure P (param: access thing);
    x: aliased thing;
  begin
    p(x'access);

method 2:

    type thing is record ... end record;
    type thing_access is access all thing;
    procedure P (param: thing_access);
    x: aliased thing;
  begin
    p(x'access);

The type thing_access is an extra junk type that has no other use 
in the program.  No actual objects of type thing_access are ever
declared or used.  It is just there to allow the parameter to be
declared.  This extra type is not needed with method 1 of declaring P.

To me the declaration of thing_access is extra useless baggage.

- Mitch




^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~1996-03-26  0:00 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1996-03-22  0:00 parameters in bindings Mitch Gart
1996-03-22  0:00 ` Robert Dewar
1996-03-26  0:00   ` Mitch Gart
1996-03-26  0:00     ` Robert Dewar
1996-03-23  0:00 ` Adam Beneschan

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox