[comp.lang.ada] A Problem With Access Types

bradford@SKL-CRC.ARPA.UUCP (04/08/87)

I am writing a program which manipulates a large, complex data structure.
The data structure consists of many embedded records and arrays
of records. I wish to have a procedure update a particular record within
this structure, and what I tried to do originally was to simply create
an access type variable for the record type and then have this access
variable refer to the record and then pass the access variable to the
procedure. The following segment represents what I tried to do:

     type A_REC is
       record
          ...
       end;

     type A_ACCESS is access A_REC;

     A : A_REC;
     A_A : A_ACCESS;

     begin
         ...
         A_A := A;  -- Also tried  A_A := A_ACCESS(A);
         UPDATE(A_A);
         ...
     end;

Ada (VAX Ada 1.3) won't let me do this, and after re-reading the LRM,
it seems that this is consistent with the LRM. So I have to do it some
other way. Some options are: 

       1) Pass the whole structure and require the called procedure to
          know the structure (I really don't like this option).

       2) Copy the appropriate record, pass the copy as  an inout parameter,
          and update the record from the returned copy.

       3) Give up and quit (but that means I won't get paid and I really
          like getting paid).

Option 2 is workable for the problem I described above, but having access
types would be easier for a similar, related problem (which I won't go into
here). Can anyone supply another altrernative, or perhaps a way of using access
types like I wanted to originally. I would be most grateful.


Bob Bradford

callen@inmet.UUCP (04/10/87)

Try something like this (but be forewarned that the code is not necessarily
going to be portable):

with Unchecked_Conversion;
with System;
...
     type A_REC is
       record
          ...
       end;

     type A_ACCESS is access A_REC;

     function Make_Pointer is new Unchecked_Conversion(
       SOURCE=>System.Address, TARGET=>A_ACCESS);

     A : A_REC;
     A_A : A_ACCESS;

     begin
         ...
         A_A := Make_Pointer(A'Address);  
         UPDATE(A_A);
         ...
     end;

-- Jerry Callen
   Intermetrics, Inc.
   733 Concord Ave.
   Cambridge, MA 01238
   (617) 661-1840

   ...{ihnp4,ima}!inmet!ada-uts!callen

jesup@steinmetz.steinmetz.UUCP (Randell Jesup) (04/12/87)

In article <8704081652.AA09954@skl-crc.ARPA> bradford@SKL-CRC.ARPA (Bob Bradford) writes:
>I am writing a program which manipulates a large, complex data structure.
>The data structure consists of many embedded records and arrays
>of records. I wish to have a procedure update a particular record within
...
>     type A_REC is
>       record
>          ...
>       end;
>
>     type A_ACCESS is access A_REC;
>
>     A : A_REC;
>     A_A : A_ACCESS;
>
>     begin
>         ...
>         A_A := A;  -- Also tried  A_A := A_ACCESS(A);
>         UPDATE(A_A);
>         ...
>     end;
...  [Vax ada doesn't like it, nor does the LRM]
>Bob Bradford

They doen't like for one reason: A (which is of type A_REC) is a declared
object, not an allocated one.  An access variable cannot refer to anything that
was not created by an allocator, and therefor cannot be set to point to
your static variable (A).

The way to make it work is to make something like this:

type A_REC is
  record
    ...
  end record;

type A_ACCESS is access A_REC;

A : A_ACCESS;  -- Note!

A_A : A_ACCESS;

begin
  ...
  A := new A_REC...
  ...
  A_A := A;
  UPDATE(A_A);
  ...
end

	Randell Jesup
	jesup@steinmetz.uucp
	jesup@ge-crd.arpa

dik@mcvax.UUCP (04/12/87)

In article <124000003@inmet> callen@inmet.UUCP writes:
 > 
 > Try something like this (but be forewarned that the code is not necessarily
 > going to be portable):
Nor is it going to be fool-proof.
 > 
 > with Unchecked_Conversion;
 > with System;
 > ...
 >      type A_REC is
 >        record
 >           ...
 >        end;
 > 
 >      type A_ACCESS is access A_REC;
 > 
 >      function Make_Pointer is new Unchecked_Conversion(
 >        SOURCE=>System.Address, TARGET=>A_ACCESS);
 > 
 >      A : A_REC;
 >      A_A : A_ACCESS;
Ah, yes, the pointer to the stack.  Note however that your contents
might get lost while youre pointer still exists.  (And no, you do
not need UNCHECKED_DEALLOCATION; the contents will deallocate
themselves.)
Useful?  Maybe.
Portable?  Probably yes.
Advisable?  Definitely no.
-- 
dik t. winter, cwi, amsterdam, nederland
INTERNET   : dik@cwi.nl
BITNET/EARN: dik@mcvax

systeam@gmdka.UUCP (04/22/87)

Could it be that you only want the effect of passing your record
by reference to the procedure UPDATE so that no big chuncks of memory get 
copied around? If so, please note that any good Ada compiler (e.g. ours) uses
the call by reference mechanism for in out parameters of your type.

My Address:
Dr. Peter Dencker
SYSTEAM KG Dr. Winterstein
Am Rueppurer Schloss 7
D 7500 Karlsruhe 51
West Germany

UUCP-mail:  systeam@gmdka.uucp