comp.lang.ada
 help / color / mirror / Atom feed
* Addressing functions
@ 1994-12-13  1:36 Bill Buckley
  1994-12-13 10:14 ` Robert I. Eachus
                   ` (3 more replies)
  0 siblings, 4 replies; 15+ messages in thread
From: Bill Buckley @ 1994-12-13  1:36 UTC (permalink / raw)


 
High Ada lovers, I've got a question on storing subprogram address in 
Ada.  I know I can get the address of a subprogram via the ADDRESS 
attribute in Ada but can not figure a way to use it.  I don't have any 
immediate need for such a procedure but it has my old C-C++ courisity 
wondering.  For instance if I were to have an array of subprogram addresses
A(1..2) => (1 => Print1'ADDRESS,
            2 => Print2'ADDRESS);
how could I implement the calling these functions (note : I know the 
syntax above is wrong but can't get this simple editor to back up to 
change it).  I have heard from several other Ada programmers that this 
may not be possible. 

--
Bill Buckley :-)



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

* Re: Addressing functions
  1994-12-13  1:36 Addressing functions Bill Buckley
@ 1994-12-13 10:14 ` Robert I. Eachus
  1994-12-14 13:59   ` Theodore E. Dennison
                     ` (2 more replies)
  1994-12-13 19:04 ` Bob Duff
                   ` (2 subsequent siblings)
  3 siblings, 3 replies; 15+ messages in thread
From: Robert I. Eachus @ 1994-12-13 10:14 UTC (permalink / raw)


In article <3citrc$bb5@earth.usa.net> wbuckley@earth (Bill Buckley) writes:

 > For instance if I were to have an array of subprogram addresses
 > A(1..2) => (1 => Print1'ADDRESS,
 >             2 => Print2'ADDRESS);
 > how could I implement the calling these functions...I have heard
 > from several other Ada programmers that this may not be possible.

   First, calling any subprogram given its address is, in Ada,
implementation specific, and you should check with the Appendix F for
the compiler you use to find out what restrictions, if any, are
imposed.  Typical restrictions are that the subprogram may not require
an enivironment to be passed to it, or that the calling conventions
expected match.

   Having said that, it is legal Ada (83 & 95) to say:

   declare
     procedure Foo;
     pragma INTERFACE(Ada, Foo);
     for Foo use at A(n);
     -- obsolescent but supported in Ada 9X, preferred is:
     -- for Foo'ADDRESS use A(n);
   begin
     Foo;
   end;

   Of course, any such program is erroneous if the profile of the
procedure located at A(n) does not match that of Foo.

   Note that the address in an address clause is not required or
expected to be static.
--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...



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

* Re: Addressing functions
  1994-12-13  1:36 Addressing functions Bill Buckley
  1994-12-13 10:14 ` Robert I. Eachus
@ 1994-12-13 19:04 ` Bob Duff
  1994-12-14  1:48 ` Michael Feldman
  1994-12-14 12:33 ` Addressing functions Mitch Gart
  3 siblings, 0 replies; 15+ messages in thread
From: Bob Duff @ 1994-12-13 19:04 UTC (permalink / raw)


In article <3citrc$bb5@earth.usa.net>, Bill Buckley <wbuckley@earth> wrote:
> 
> ...I know I can get the address of a subprogram via the ADDRESS 
>attribute in Ada but can not figure a way to use it.

In Ada83, there is no portable way to call such a subprogram.  If you
know the machine-level calling conventions used by your compiler, you
can write a machine code insertion that does, but that's pretty nasty.

In Ada 9X, you can use access-to-subprogram types:

    type String_Procedure is access procedure (S: String);
    X: String_Procedure := Text_IO.Put'Access;

Now you can call X like this:

    X("Hello, world");

which means the same as this:

    X.all("Hello, world");
-- 
Bob Duff                                bobduff@inmet.com
Oak Tree Software, Inc.
Ada 9X Mapping/Revision Team (Intermetrics, Inc.)



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

* Re: Addressing functions
  1994-12-13  1:36 Addressing functions Bill Buckley
  1994-12-13 10:14 ` Robert I. Eachus
  1994-12-13 19:04 ` Bob Duff
@ 1994-12-14  1:48 ` Michael Feldman
  1994-12-16 14:53   ` Robert Dewar
  1994-12-17  7:23   ` Addressing functions (long) Michael M. Bishop
  1994-12-14 12:33 ` Addressing functions Mitch Gart
  3 siblings, 2 replies; 15+ messages in thread
From: Michael Feldman @ 1994-12-14  1:48 UTC (permalink / raw)


In article <3citrc$bb5@earth.usa.net>, Bill Buckley <wbuckley@earth> wrote:
> 
>High Ada lovers, I've got a question on storing subprogram address in 
>Ada.  I know I can get the address of a subprogram via the ADDRESS 
>attribute in Ada but can not figure a way to use it.  I don't have any 
>immediate need for such a procedure but it has my old C-C++ courisity 
>wondering.  For instance if I were to have an array of subprogram addresses
>A(1..2) => (1 => Print1'ADDRESS,
>            2 => Print2'ADDRESS);
>how could I implement the calling these functions (note : I know the 
>syntax above is wrong but can't get this simple editor to back up to 
>change it).  I have heard from several other Ada programmers that this 
>may not be possible. 

You can usually get something reasonably meaningful by casting the address
to an integer. Instantiate Unchecked_Conversion: 

FUNCTION AddressToInt IS NEW Unchecked_Conversion 
  (Source => System.Address, Target => Integer);

you can then use a normal Integer_IO instance to display it. If the
instance is called My_Int_IO, then

   My_Int_IO.Put(Item => AddressToInt(Print1'Address), Base => 16);

should display it nicely in hexadecimal.

Mike Feldman



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

* Re: Addressing functions
  1994-12-13  1:36 Addressing functions Bill Buckley
                   ` (2 preceding siblings ...)
  1994-12-14  1:48 ` Michael Feldman
@ 1994-12-14 12:33 ` Mitch Gart
  1994-12-15 16:26   ` Erich A. Pfeiffer
  3 siblings, 1 reply; 15+ messages in thread
From: Mitch Gart @ 1994-12-14 12:33 UTC (permalink / raw)


Bill Buckley (wbuckley@earth) wrote:
:  
: High Ada lovers, 

Presumably you mean "Hi" not "High" but who knows?

: I've got a question on storing subprogram address in 
: Ada.  I know I can get the address of a subprogram via the ADDRESS 
: attribute in Ada but can not figure a way to use it.  I don't have any 
: immediate need for such a procedure but it has my old C-C++ courisity 
: wondering.  For instance if I were to have an array of subprogram addresses
: A(1..2) => (1 => Print1'ADDRESS,
:             2 => Print2'ADDRESS);
: how could I implement the calling these functions (note : I know the 
: syntax above is wrong but can't get this simple editor to back up to 
: change it).  I have heard from several other Ada programmers that this 
: may not be possible. 

: --
: Bill Buckley :-)

Not possible in Ada '83, at least not possible using standard Ada.
Your compiler vendor may provide a non-standard way to do it.

Ada 95 has "access procedure" and "access function" objects which
will do what you want.

	Mitch Gart



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

* Re: Addressing functions
  1994-12-13 10:14 ` Robert I. Eachus
@ 1994-12-14 13:59   ` Theodore E. Dennison
  1994-12-16 14:18   ` Arthur Evans Jr
  1994-12-16 16:56   ` Robert Dewar
  2 siblings, 0 replies; 15+ messages in thread
From: Theodore E. Dennison @ 1994-12-14 13:59 UTC (permalink / raw)


 In article <3citrc$bb5@earth.usa.net> wbuckley@earth (Bill Buckley) writes:
 
  > For instance if I were to have an array of subprogram addresses
  > A(1..2) => (1 => Print1'ADDRESS,
  >             2 => Print2'ADDRESS);
  > how could I implement the calling these functions...I have heard
  > from several other Ada programmers that this may not be possible.
 

To get the same effect (but in a "safe" manner), why not do the
following? :

   subtype Procedure_Range is 1..2;
   procedure A (Index : in Procedure_Range) is
   begin
      case Index is
         when 1 => Print1;
         when 2 => Print2;
      end case;
   end A;

This way you are calling explicit procedures, rather than jumping
to addresses containing "Lord-only-knows-what".

There is a very good reason for a lot of what Ada prevents you from
doing.

T.E.D.



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

* Re: Addressing functions
  1994-12-14 12:33 ` Addressing functions Mitch Gart
@ 1994-12-15 16:26   ` Erich A. Pfeiffer
  0 siblings, 0 replies; 15+ messages in thread
From: Erich A. Pfeiffer @ 1994-12-15 16:26 UTC (permalink / raw)


>Bill Buckley (wbuckley@earth) wrote:
>:  
>: I've got a question on storing subprogram address in 
>: Ada.  I know I can get the address of a subprogram via the ADDRESS 
>: attribute in Ada but can not figure a way to use it.  I don't have any 
>: immediate need for such a procedure but it has my old C-C++ courisity 
>: wondering.  For instance if I were to have an array of subprogram addresses
>: A(1..2) => (1 => Print1'ADDRESS,
>:             2 => Print2'ADDRESS);
>: how could I implement the calling these functions (note : I know the 
>: syntax above is wrong but can't get this simple editor to back up to 
>: change it).  I have heard from several other Ada programmers that this 
>: may not be possible. 

We implemented a "calculated GOSUB" like this in Ada83 but we had to write
a 2-line assembly routine using the Machine Code package. It is running on
a C30 processor and we used the Tartan Ada compiler. Machine code insertion
is an implementation dependent feature and it depends on your compiler 
whether you have it or not.

Best regards

(posted from my private account - I am a Software Engineer with Northrop
Grumman ESID Hawthorne Site. No, I _don't_ have a Tartan compiler running
on my system at home.....)






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

* Re: Addressing functions
  1994-12-13 10:14 ` Robert I. Eachus
  1994-12-14 13:59   ` Theodore E. Dennison
@ 1994-12-16 14:18   ` Arthur Evans Jr
  1994-12-17 17:27     ` Robert Dewar
  1994-12-17 17:32     ` Robert Dewar
  1994-12-16 16:56   ` Robert Dewar
  2 siblings, 2 replies; 15+ messages in thread
From: Arthur Evans Jr @ 1994-12-16 14:18 UTC (permalink / raw)
  Cc: Robert I. Eachus

In article <EACHUS.94Dec13101448@spectre.mitre.org>,
eachus@spectre.mitre.org (Robert I. Eachus) wrote:

>    Having said that, it is legal Ada (83 & 95) to say:
>      [deleted]
>      pragma INTERFACE(Ada, Foo);

It's clear that Ada-95 requires support of pragma interface to Ada (see
Ada-95 RM B.1(11) and 6.3.1(3)).  However, how do you conclude that
Ada-83 requires such support?  RM-83 doesn't mention Ada at all in 13.9.

Art Evans

Arthur Evans Jr, PhD        Phone: 412-963-0839
Ada Consulting              FAX:   412-963-0927
461 Fairview Road
Pittsburgh PA  15238-1933
evans@evans.pgh.pa.us



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

* Re: Addressing functions
  1994-12-14  1:48 ` Michael Feldman
@ 1994-12-16 14:53   ` Robert Dewar
  1994-12-17  7:23   ` Addressing functions (long) Michael M. Bishop
  1 sibling, 0 replies; 15+ messages in thread
From: Robert Dewar @ 1994-12-16 14:53 UTC (permalink / raw)


Michael (Feldman), I think you missed the point of the question about
address applied to subprograms. What the original poster wants is a way
of using (i.e. CALLING) these subprograms given the address.

This is of course the feature that has been added to Ada 9X. There is no
guaranteed way of doing it in Ada 83, it is completely outside the
standard. Nevertheless, it is often possible to set up kludges for
a particular compiler.

If your compiler gives the entry point of the function as the 'Address,
then at least for global level functions, you can probably use some
assembly glue to call them. This won't work for nested functions, because
you won't be able to materialize the static link or display.

On some compilers it will work to do something like:

      procedure p is ...  

      x : address;

      x := p'address;  -- or whatever ..

now to call the procedure:

      declare
         procedure dummy;
         for dummy'address use x;
         pragma interface (Ada, dummy);
      begin
	 dummy;
      end;

this is not guaranteed to work, but it may work on some compilers.

Best answer to original question: use Ada 95!




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

* Re: Addressing functions
  1994-12-13 10:14 ` Robert I. Eachus
  1994-12-14 13:59   ` Theodore E. Dennison
  1994-12-16 14:18   ` Arthur Evans Jr
@ 1994-12-16 16:56   ` Robert Dewar
  2 siblings, 0 replies; 15+ messages in thread
From: Robert Dewar @ 1994-12-16 16:56 UTC (permalink / raw)


Robert Eachus points out the same possible solution (using an address
clause) that I did, but he is too optimistic about its chance of success.

The effect of this sequence of code, or even its legality, cannot be
determined from the RM. It works on some compilers but not on others.
That you expect it might work is based on knowledge of implementation
models. There are many legitimate reasons for a compiler to reject the
program as illegal, and also many legitimate reasons for a compiler
to accept the program and then do the wrong thing.

At ome point CIFO included a requirement that this approach work, but 
CIFO is not a standard, and so you can't count on this.

Ada/95 solves this problem directly!




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

* Re: Addressing functions (long)
  1994-12-14  1:48 ` Michael Feldman
  1994-12-16 14:53   ` Robert Dewar
@ 1994-12-17  7:23   ` Michael M. Bishop
  1994-12-18  6:53     ` Bill Buckley
  1 sibling, 1 reply; 15+ messages in thread
From: Michael M. Bishop @ 1994-12-17  7:23 UTC (permalink / raw)


In article <3clisk$9th@felix.seas.gwu.edu>,
Michael Feldman <mfeldman@seas.gwu.edu> wrote:
>In article <3citrc$bb5@earth.usa.net>, Bill Buckley <wbuckley@earth> wrote:
>> 
>>High Ada lovers, I've got a question on storing subprogram address in 
>>Ada.  I know I can get the address of a subprogram via the ADDRESS 
>>attribute in Ada but can not figure a way to use it.  I don't have any 
>>immediate need for such a procedure but it has my old C-C++ courisity 
>>wondering.  For instance if I were to have an array of subprogram addresses
>>A(1..2) => (1 => Print1'ADDRESS,
>>            2 => Print2'ADDRESS);
>>how could I implement the calling these functions (note : I know the 
>>syntax above is wrong but can't get this simple editor to back up to 
>>change it).  I have heard from several other Ada programmers that this 
>>may not be possible. 
>
>You can usually get something reasonably meaningful by casting the address
>to an integer. Instantiate Unchecked_Conversion: 
>
>FUNCTION AddressToInt IS NEW Unchecked_Conversion 
>  (Source => System.Address, Target => Integer);
>
>you can then use a normal Integer_IO instance to display it. If the
>instance is called My_Int_IO, then
>
>   My_Int_IO.Put(Item => AddressToInt(Print1'Address), Base => 16);
>
>should display it nicely in hexadecimal.
>
>Mike Feldman

I think Bill is asking about a way to call the above functions whose
addresses are stored in the array. I've done this by passing the
subprogram addresses to a C function that does the actual calling. This
might be a compiler-specific solution as it uses pragmas. I'm using
SunAda version 1.1 on SunOS 4.1. The C routine looks like this (in this
example, I'm passing a parameter back to the Ada procedure):

pragma Wierd_C_Stuff (On);

void call_procedure_with_a_parameter (proc_addr, parm)
  int    proc_addr;
  double parm;  /* use whatever parameter type you need */
{
  union {
    int procedure_address;
    void (*procedure) ();
  } proc_union;

  proc_union.procedure_address = proc_addr;
  proc_union.procedure (parm);
}

pragma Wierd_C_Stuff (Off);

I may have messed up the syntax for the procedure pointer member of the
union. I apologize if I did. In order to interface the above C function
with Ada, I need a couple of pragmas.

pragma Interface (C, call_procedure_with_a_parameter);

procedure Procedure_To_Be_Called
  (Parm : in Float) is  -- in SunAda, Float is equivalent to C's double
begin
  < whatever goes here >
end Procedure_To_Be_Called;

pragma External (C, Procedure_To_Be_Called);

procedure Call_Procedure_By_Address is
begin
  Call_Procedure_With_A_Parameter (Procedure_To_Be_Called'address,
      3.1416);
end Call_Procedure_By_Address;

The pragma External informs the compiler that Procedure_To_Be_Called
will be called by a C function. I hope this helps.


-- 
| Mike Bishop              | The opinions expressed here reflect    |
| bishopm@source.asset.com | those of this station, its management, |
| Member: Team Ada         | and the entire world.                  |



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

* Re: Addressing functions
  1994-12-16 14:18   ` Arthur Evans Jr
@ 1994-12-17 17:27     ` Robert Dewar
  1994-12-17 17:32     ` Robert Dewar
  1 sibling, 0 replies; 15+ messages in thread
From: Robert Dewar @ 1994-12-17 17:27 UTC (permalink / raw)


Art Evans asks if Ada 83 requires support of pragma Interface to Ada. THe
answer is clearly NO, in fact Ada 83 does not require that you support
pragma Interface for any language.

This is one of several respects in which the code example from Bob Eachus
may be considered illegal by an Ada 83 compiler.




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

* Re: Addressing functions
  1994-12-16 14:18   ` Arthur Evans Jr
  1994-12-17 17:27     ` Robert Dewar
@ 1994-12-17 17:32     ` Robert Dewar
  1994-12-18  6:44       ` Bill Buckley
  1 sibling, 1 reply; 15+ messages in thread
From: Robert Dewar @ 1994-12-17 17:32 UTC (permalink / raw)


Moreover, Art reads into B.1(11) a requirement in Ada 95 to support
pragma Interface (Ada,...)

I don't see any such requirement. The sentence in 11 merely says that
the convention name Ada is not implementation dependent, it does not
say that you have to support it. Obviously you can't support pragma
Intrinsic for arbitrary entities, so clearly the implementation can
decide in general what pragma Import's to allow (there is implementation
advice in para 41, but that is only advice).




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

* Re: Addressing functions
  1994-12-17 17:32     ` Robert Dewar
@ 1994-12-18  6:44       ` Bill Buckley
  0 siblings, 0 replies; 15+ messages in thread
From: Bill Buckley @ 1994-12-18  6:44 UTC (permalink / raw)


Just wanted to thank everone for reply.  I now beleive the best solution 
to my question is Ada 95.  Thanks

--
Bill Buckley :-)



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

* Re: Addressing functions (long)
  1994-12-17  7:23   ` Addressing functions (long) Michael M. Bishop
@ 1994-12-18  6:53     ` Bill Buckley
  0 siblings, 0 replies; 15+ messages in thread
From: Bill Buckley @ 1994-12-18  6:53 UTC (permalink / raw)


:Thanks for your answer Michael.  As I have no immediate need for the 
solution I think Ada 95 is the best solution but will certainly 
keep your solutionn in my bag of tricks if needed before having an 
Ada 95 compiler at my disposal.

--
Bill Buckley :-)



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

end of thread, other threads:[~1994-12-18  6:53 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1994-12-13  1:36 Addressing functions Bill Buckley
1994-12-13 10:14 ` Robert I. Eachus
1994-12-14 13:59   ` Theodore E. Dennison
1994-12-16 14:18   ` Arthur Evans Jr
1994-12-17 17:27     ` Robert Dewar
1994-12-17 17:32     ` Robert Dewar
1994-12-18  6:44       ` Bill Buckley
1994-12-16 16:56   ` Robert Dewar
1994-12-13 19:04 ` Bob Duff
1994-12-14  1:48 ` Michael Feldman
1994-12-16 14:53   ` Robert Dewar
1994-12-17  7:23   ` Addressing functions (long) Michael M. Bishop
1994-12-18  6:53     ` Bill Buckley
1994-12-14 12:33 ` Addressing functions Mitch Gart
1994-12-15 16:26   ` Erich A. Pfeiffer

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